blob: 5acb5e16e536fa3168d23db5c4699f9f15607aa2 [file] [log] [blame]
[email protected]44106182012-04-06 03:53:021// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]1c4947f2009-01-15 22:25:112// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]f7b98b32013-02-05 08:14:155#include "base/synchronization/waitable_event_watcher.h"
6
[email protected]329be052013-02-04 18:14:287#include "base/bind.h"
8#include "base/callback.h"
avi9b6f42932015-12-26 22:15:149#include "base/macros.h"
atuchin54d83152017-05-10 06:30:0110#include "base/memory/ptr_util.h"
[email protected]f7b98b32013-02-05 08:14:1511#include "base/run_loop.h"
[email protected]44f9c952011-01-02 06:05:3912#include "base/synchronization/waitable_event.h"
Sami Kyostila3f49cb572018-11-19 13:01:0913#include "base/test/scoped_task_environment.h"
[email protected]ce072a72010-12-31 20:02:1614#include "base/threading/platform_thread.h"
atuchin54d83152017-05-10 06:30:0115#include "base/threading/sequenced_task_runner_handle.h"
Sami Kyostila3f49cb572018-11-19 13:01:0916#include "base/threading/thread_task_runner_handle.h"
avi9b6f42932015-12-26 22:15:1417#include "build/build_config.h"
[email protected]1c4947f2009-01-15 22:25:1118#include "testing/gtest/include/gtest/gtest.h"
19
[email protected]44f9c952011-01-02 06:05:3920namespace base {
[email protected]1c4947f2009-01-15 22:25:1121
22namespace {
23
Sami Kyostila3f49cb572018-11-19 13:01:0924// The main thread types on which each waitable event should be tested.
25const test::ScopedTaskEnvironment::MainThreadType testing_main_threads[] = {
26 test::ScopedTaskEnvironment::MainThreadType::DEFAULT,
27 test::ScopedTaskEnvironment::MainThreadType::IO,
[email protected]840246b2012-07-18 08:06:5028#if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
Sami Kyostila3f49cb572018-11-19 13:01:0929 test::ScopedTaskEnvironment::MainThreadType::UI,
[email protected]840246b2012-07-18 08:06:5030#endif
31};
32
[email protected]329be052013-02-04 18:14:2833void QuitWhenSignaled(WaitableEvent* event) {
Gabriel Charette53a9ef812017-07-26 12:36:2334 RunLoop::QuitCurrentWhenIdleDeprecated();
[email protected]329be052013-02-04 18:14:2835}
[email protected]1eaa54792013-01-31 23:14:2736
[email protected]329be052013-02-04 18:14:2837class DecrementCountContainer {
[email protected]1eaa54792013-01-31 23:14:2738 public:
Robert Sesekb44f8962017-06-30 21:21:1339 explicit DecrementCountContainer(int* counter) : counter_(counter) {}
[email protected]329be052013-02-04 18:14:2840 void OnWaitableEventSignaled(WaitableEvent* object) {
atuchin54d83152017-05-10 06:30:0141 // NOTE: |object| may be already deleted.
[email protected]1c4947f2009-01-15 22:25:1142 --(*counter_);
43 }
Robert Sesekb44f8962017-06-30 21:21:1344
[email protected]1c4947f2009-01-15 22:25:1145 private:
46 int* counter_;
47};
48
Robert Sesek3b3333772017-06-30 18:21:5649} // namespace
50
51class WaitableEventWatcherTest
Sami Kyostila3f49cb572018-11-19 13:01:0952 : public testing::TestWithParam<
53 test::ScopedTaskEnvironment::MainThreadType> {};
Robert Sesek3b3333772017-06-30 18:21:5654
Robert Sesekcfab3ad2017-08-01 16:25:4355TEST_P(WaitableEventWatcherTest, BasicSignalManual) {
Sami Kyostila3f49cb572018-11-19 13:01:0956 test::ScopedTaskEnvironment scoped_task_environment(GetParam());
[email protected]1c4947f2009-01-15 22:25:1157
58 // A manual-reset event that is not yet signaled.
gab75d72332016-06-01 21:15:3359 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
60 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]1c4947f2009-01-15 22:25:1161
62 WaitableEventWatcher watcher;
Hajime Hoshi138652c92018-01-12 15:11:4463 watcher.StartWatching(&event, BindOnce(&QuitWhenSignaled),
64 SequencedTaskRunnerHandle::Get());
[email protected]1c4947f2009-01-15 22:25:1165
66 event.Signal();
67
fdoray10224582016-06-30 18:17:3968 RunLoop().Run();
Robert Sesekcfab3ad2017-08-01 16:25:4369
70 EXPECT_TRUE(event.IsSignaled());
71}
72
73TEST_P(WaitableEventWatcherTest, BasicSignalAutomatic) {
Sami Kyostila3f49cb572018-11-19 13:01:0974 test::ScopedTaskEnvironment scoped_task_environment(GetParam());
Robert Sesekcfab3ad2017-08-01 16:25:4375
76 WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC,
77 WaitableEvent::InitialState::NOT_SIGNALED);
78
79 WaitableEventWatcher watcher;
Hajime Hoshi138652c92018-01-12 15:11:4480 watcher.StartWatching(&event, BindOnce(&QuitWhenSignaled),
81 SequencedTaskRunnerHandle::Get());
Robert Sesekcfab3ad2017-08-01 16:25:4382
83 event.Signal();
84
85 RunLoop().Run();
86
87 // The WaitableEventWatcher consumes the event signal.
88 EXPECT_FALSE(event.IsSignaled());
[email protected]1c4947f2009-01-15 22:25:1189}
90
Robert Sesek3b3333772017-06-30 18:21:5691TEST_P(WaitableEventWatcherTest, BasicCancel) {
Sami Kyostila3f49cb572018-11-19 13:01:0992 test::ScopedTaskEnvironment scoped_task_environment(GetParam());
[email protected]1c4947f2009-01-15 22:25:1193
94 // A manual-reset event that is not yet signaled.
gab75d72332016-06-01 21:15:3395 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
96 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]1c4947f2009-01-15 22:25:1197
98 WaitableEventWatcher watcher;
99
Hajime Hoshi138652c92018-01-12 15:11:44100 watcher.StartWatching(&event, BindOnce(&QuitWhenSignaled),
101 SequencedTaskRunnerHandle::Get());
[email protected]1c4947f2009-01-15 22:25:11102
103 watcher.StopWatching();
104}
105
Robert Sesek3b3333772017-06-30 18:21:56106TEST_P(WaitableEventWatcherTest, CancelAfterSet) {
Sami Kyostila3f49cb572018-11-19 13:01:09107 test::ScopedTaskEnvironment scoped_task_environment(GetParam());
[email protected]1c4947f2009-01-15 22:25:11108
109 // A manual-reset event that is not yet signaled.
gab75d72332016-06-01 21:15:33110 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
111 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]1c4947f2009-01-15 22:25:11112
113 WaitableEventWatcher watcher;
114
115 int counter = 1;
[email protected]329be052013-02-04 18:14:28116 DecrementCountContainer delegate(&counter);
tzik130cfd0c2017-04-18 03:49:05117 WaitableEventWatcher::EventCallback callback = BindOnce(
118 &DecrementCountContainer::OnWaitableEventSignaled, Unretained(&delegate));
Hajime Hoshi138652c92018-01-12 15:11:44119 watcher.StartWatching(&event, std::move(callback),
120 SequencedTaskRunnerHandle::Get());
[email protected]1c4947f2009-01-15 22:25:11121
122 event.Signal();
123
124 // Let the background thread do its business
Hajime Hoshi138652c92018-01-12 15:11:44125 PlatformThread::Sleep(TimeDelta::FromMilliseconds(30));
[email protected]1c4947f2009-01-15 22:25:11126
127 watcher.StopWatching();
128
[email protected]f7b98b32013-02-05 08:14:15129 RunLoop().RunUntilIdle();
[email protected]1c4947f2009-01-15 22:25:11130
131 // Our delegate should not have fired.
132 EXPECT_EQ(1, counter);
133}
134
Sami Kyostila3f49cb572018-11-19 13:01:09135TEST_P(WaitableEventWatcherTest, OutlivesTaskEnvironment) {
136 // Simulate a task environment that dies before an WaitableEventWatcher. This
[email protected]1c4947f2009-01-15 22:25:11137 // ordinarily doesn't happen when people use the Thread class, but it can
138 // happen when people use the Singleton pattern or atexit.
gab75d72332016-06-01 21:15:33139 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
140 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]1c4947f2009-01-15 22:25:11141 {
Hajime Hoshi138652c92018-01-12 15:11:44142 std::unique_ptr<WaitableEventWatcher> watcher;
[email protected]1c4947f2009-01-15 22:25:11143 {
Sami Kyostila3f49cb572018-11-19 13:01:09144 test::ScopedTaskEnvironment scoped_task_environment(GetParam());
Hajime Hoshi138652c92018-01-12 15:11:44145 watcher = std::make_unique<WaitableEventWatcher>();
[email protected]1c4947f2009-01-15 22:25:11146
Hajime Hoshi138652c92018-01-12 15:11:44147 watcher->StartWatching(&event, BindOnce(&QuitWhenSignaled),
148 SequencedTaskRunnerHandle::Get());
[email protected]1c4947f2009-01-15 22:25:11149 }
150 }
151}
152
Robert Sesekcfab3ad2017-08-01 16:25:43153TEST_P(WaitableEventWatcherTest, SignaledAtStartManual) {
Sami Kyostila3f49cb572018-11-19 13:01:09154 test::ScopedTaskEnvironment scoped_task_environment(GetParam());
Robert Sesekb44f8962017-06-30 21:21:13155
156 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
157 WaitableEvent::InitialState::SIGNALED);
158
159 WaitableEventWatcher watcher;
Hajime Hoshi138652c92018-01-12 15:11:44160 watcher.StartWatching(&event, BindOnce(&QuitWhenSignaled),
161 SequencedTaskRunnerHandle::Get());
Robert Sesekb44f8962017-06-30 21:21:13162
163 RunLoop().Run();
Robert Sesekcfab3ad2017-08-01 16:25:43164
165 EXPECT_TRUE(event.IsSignaled());
166}
167
168TEST_P(WaitableEventWatcherTest, SignaledAtStartAutomatic) {
Sami Kyostila3f49cb572018-11-19 13:01:09169 test::ScopedTaskEnvironment scoped_task_environment(GetParam());
Robert Sesekcfab3ad2017-08-01 16:25:43170
171 WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC,
172 WaitableEvent::InitialState::SIGNALED);
173
174 WaitableEventWatcher watcher;
Hajime Hoshi138652c92018-01-12 15:11:44175 watcher.StartWatching(&event, BindOnce(&QuitWhenSignaled),
176 SequencedTaskRunnerHandle::Get());
Robert Sesekcfab3ad2017-08-01 16:25:43177
178 RunLoop().Run();
179
180 // The watcher consumes the event signal.
181 EXPECT_FALSE(event.IsSignaled());
Robert Sesekb44f8962017-06-30 21:21:13182}
183
184TEST_P(WaitableEventWatcherTest, StartWatchingInCallback) {
Sami Kyostila3f49cb572018-11-19 13:01:09185 test::ScopedTaskEnvironment scoped_task_environment(GetParam());
Robert Sesekb44f8962017-06-30 21:21:13186
187 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
188 WaitableEvent::InitialState::NOT_SIGNALED);
189
190 WaitableEventWatcher watcher;
191 watcher.StartWatching(
Hajime Hoshi138652c92018-01-12 15:11:44192 &event,
193 BindOnce(
194 [](WaitableEventWatcher* watcher, WaitableEvent* event) {
195 // |event| is manual, so the second watcher will run
196 // immediately.
197 watcher->StartWatching(event, BindOnce(&QuitWhenSignaled),
198 SequencedTaskRunnerHandle::Get());
199 },
200 &watcher),
201 SequencedTaskRunnerHandle::Get());
Robert Sesekb44f8962017-06-30 21:21:13202
203 event.Signal();
204
205 RunLoop().Run();
206}
207
Robert Sesekcfab3ad2017-08-01 16:25:43208TEST_P(WaitableEventWatcherTest, MultipleWatchersManual) {
Sami Kyostila3f49cb572018-11-19 13:01:09209 test::ScopedTaskEnvironment scoped_task_environment(GetParam());
Robert Sesekcfab3ad2017-08-01 16:25:43210
211 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
212 WaitableEvent::InitialState::NOT_SIGNALED);
213
214 int counter1 = 0;
215 int counter2 = 0;
216
217 auto callback = [](RunLoop* run_loop, int* counter, WaitableEvent* event) {
218 ++(*counter);
219 run_loop->QuitWhenIdle();
220 };
221
222 RunLoop run_loop;
223
224 WaitableEventWatcher watcher1;
225 watcher1.StartWatching(
Hajime Hoshi138652c92018-01-12 15:11:44226 &event, BindOnce(callback, Unretained(&run_loop), Unretained(&counter1)),
227 SequencedTaskRunnerHandle::Get());
Robert Sesekcfab3ad2017-08-01 16:25:43228
229 WaitableEventWatcher watcher2;
230 watcher2.StartWatching(
Hajime Hoshi138652c92018-01-12 15:11:44231 &event, BindOnce(callback, Unretained(&run_loop), Unretained(&counter2)),
232 SequencedTaskRunnerHandle::Get());
Robert Sesekcfab3ad2017-08-01 16:25:43233
234 event.Signal();
235 run_loop.Run();
236
237 EXPECT_EQ(1, counter1);
238 EXPECT_EQ(1, counter2);
239 EXPECT_TRUE(event.IsSignaled());
240}
241
242// Tests that only one async waiter gets called back for an auto-reset event.
243TEST_P(WaitableEventWatcherTest, MultipleWatchersAutomatic) {
Sami Kyostila3f49cb572018-11-19 13:01:09244 test::ScopedTaskEnvironment scoped_task_environment(GetParam());
Robert Sesekcfab3ad2017-08-01 16:25:43245
246 WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC,
247 WaitableEvent::InitialState::NOT_SIGNALED);
248
249 int counter1 = 0;
250 int counter2 = 0;
251
252 auto callback = [](RunLoop** run_loop, int* counter, WaitableEvent* event) {
253 ++(*counter);
254 (*run_loop)->QuitWhenIdle();
255 };
256
257 // The same RunLoop instance cannot be Run more than once, and it is
258 // undefined which watcher will get called back first. Have the callback
259 // dereference this pointer to quit the loop, which will be updated on each
260 // Run.
261 RunLoop* current_run_loop;
262
263 WaitableEventWatcher watcher1;
264 watcher1.StartWatching(
265 &event,
Hajime Hoshi138652c92018-01-12 15:11:44266 BindOnce(callback, Unretained(&current_run_loop), Unretained(&counter1)),
267 SequencedTaskRunnerHandle::Get());
Robert Sesekcfab3ad2017-08-01 16:25:43268
269 WaitableEventWatcher watcher2;
270 watcher2.StartWatching(
271 &event,
Hajime Hoshi138652c92018-01-12 15:11:44272 BindOnce(callback, Unretained(&current_run_loop), Unretained(&counter2)),
273 SequencedTaskRunnerHandle::Get());
Robert Sesekcfab3ad2017-08-01 16:25:43274
275 event.Signal();
276 {
277 RunLoop run_loop;
278 current_run_loop = &run_loop;
279 run_loop.Run();
280 }
281
282 // Only one of the waiters should have been signaled.
283 EXPECT_TRUE((counter1 == 1) ^ (counter2 == 1));
284
285 EXPECT_FALSE(event.IsSignaled());
286
287 event.Signal();
288 {
289 RunLoop run_loop;
290 current_run_loop = &run_loop;
291 run_loop.Run();
292 }
293
294 EXPECT_FALSE(event.IsSignaled());
295
296 // The other watcher should have been signaled.
297 EXPECT_EQ(1, counter1);
298 EXPECT_EQ(1, counter2);
299}
300
Robert Sesek3b3333772017-06-30 18:21:56301// To help detect errors around deleting WaitableEventWatcher, an additional
302// bool parameter is used to test sleeping between watching and deletion.
303class WaitableEventWatcherDeletionTest
Sami Kyostila3f49cb572018-11-19 13:01:09304 : public testing::TestWithParam<
305 std::tuple<test::ScopedTaskEnvironment::MainThreadType, bool>> {};
Robert Sesek3b3333772017-06-30 18:21:56306
307TEST_P(WaitableEventWatcherDeletionTest, DeleteUnder) {
Sami Kyostila3f49cb572018-11-19 13:01:09308 test::ScopedTaskEnvironment::MainThreadType main_thread_type;
Robert Sesek3b3333772017-06-30 18:21:56309 bool delay_after_delete;
Sami Kyostila3f49cb572018-11-19 13:01:09310 std::tie(main_thread_type, delay_after_delete) = GetParam();
Robert Sesek3b3333772017-06-30 18:21:56311
[email protected]c891ab92009-03-26 18:28:19312 // Delete the WaitableEvent out from under the Watcher. This is explictly
313 // allowed by the interface.
314
Sami Kyostila3f49cb572018-11-19 13:01:09315 test::ScopedTaskEnvironment scoped_task_environment(main_thread_type);
[email protected]c891ab92009-03-26 18:28:19316
317 {
318 WaitableEventWatcher watcher;
319
atuchin54d83152017-05-10 06:30:01320 auto* event = new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC,
321 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]329be052013-02-04 18:14:28322
Hajime Hoshi138652c92018-01-12 15:11:44323 watcher.StartWatching(event, BindOnce(&QuitWhenSignaled),
324 SequencedTaskRunnerHandle::Get());
atuchin54d83152017-05-10 06:30:01325
326 if (delay_after_delete) {
327 // On Windows that sleep() improves the chance to catch some problems.
328 // It postpones the dtor |watcher| (which immediately cancel the waiting)
329 // and gives some time to run to a created background thread.
330 // Unfortunately, that thread is under OS control and we can't
331 // manipulate it directly.
Hajime Hoshi138652c92018-01-12 15:11:44332 PlatformThread::Sleep(TimeDelta::FromMilliseconds(30));
atuchin54d83152017-05-10 06:30:01333 }
334
[email protected]c891ab92009-03-26 18:28:19335 delete event;
336 }
337}
338
Robert Sesek3b3333772017-06-30 18:21:56339TEST_P(WaitableEventWatcherDeletionTest, SignalAndDelete) {
Sami Kyostila3f49cb572018-11-19 13:01:09340 test::ScopedTaskEnvironment::MainThreadType main_thread_type;
Robert Sesek3b3333772017-06-30 18:21:56341 bool delay_after_delete;
Sami Kyostila3f49cb572018-11-19 13:01:09342 std::tie(main_thread_type, delay_after_delete) = GetParam();
Robert Sesek3b3333772017-06-30 18:21:56343
atuchin54d83152017-05-10 06:30:01344 // Signal and immediately delete the WaitableEvent out from under the Watcher.
345
Sami Kyostila3f49cb572018-11-19 13:01:09346 test::ScopedTaskEnvironment scoped_task_environment(main_thread_type);
atuchin54d83152017-05-10 06:30:01347
348 {
349 WaitableEventWatcher watcher;
350
Jeremy Roman9532f252017-08-16 23:27:24351 auto event = std::make_unique<WaitableEvent>(
atuchin54d83152017-05-10 06:30:01352 WaitableEvent::ResetPolicy::AUTOMATIC,
353 WaitableEvent::InitialState::NOT_SIGNALED);
354
Hajime Hoshi138652c92018-01-12 15:11:44355 watcher.StartWatching(event.get(), BindOnce(&QuitWhenSignaled),
356 SequencedTaskRunnerHandle::Get());
atuchin54d83152017-05-10 06:30:01357 event->Signal();
358 event.reset();
359
360 if (delay_after_delete) {
361 // On Windows that sleep() improves the chance to catch some problems.
362 // It postpones the dtor |watcher| (which immediately cancel the waiting)
363 // and gives some time to run to a created background thread.
364 // Unfortunately, that thread is under OS control and we can't
365 // manipulate it directly.
Hajime Hoshi138652c92018-01-12 15:11:44366 PlatformThread::Sleep(TimeDelta::FromMilliseconds(30));
atuchin54d83152017-05-10 06:30:01367 }
368
369 // Wait for the watcher callback.
370 RunLoop().Run();
371 }
372}
373
Robert Sesek6d38e782017-07-13 00:46:50374// Tests deleting the WaitableEventWatcher between signaling the event and
375// when the callback should be run.
376TEST_P(WaitableEventWatcherDeletionTest, DeleteWatcherBeforeCallback) {
Sami Kyostila3f49cb572018-11-19 13:01:09377 test::ScopedTaskEnvironment::MainThreadType main_thread_type;
Robert Sesek6d38e782017-07-13 00:46:50378 bool delay_after_delete;
Sami Kyostila3f49cb572018-11-19 13:01:09379 std::tie(main_thread_type, delay_after_delete) = GetParam();
Robert Sesek6d38e782017-07-13 00:46:50380
Sami Kyostila3f49cb572018-11-19 13:01:09381 test::ScopedTaskEnvironment scoped_task_environment(main_thread_type);
Robert Sesek6d38e782017-07-13 00:46:50382 scoped_refptr<SingleThreadTaskRunner> task_runner =
Sami Kyostila3f49cb572018-11-19 13:01:09383 ThreadTaskRunnerHandle::Get();
Robert Sesek6d38e782017-07-13 00:46:50384
385 // Flag used to esnure that the |watcher_callback| never runs.
386 bool did_callback = false;
387
388 WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC,
389 WaitableEvent::InitialState::NOT_SIGNALED);
Jeremy Roman9532f252017-08-16 23:27:24390 auto watcher = std::make_unique<WaitableEventWatcher>();
Robert Sesek6d38e782017-07-13 00:46:50391
392 // Queue up a series of tasks:
393 // 1. StartWatching the WaitableEvent
394 // 2. Signal the event (which will result in another task getting posted to
395 // the |task_runner|)
396 // 3. Delete the WaitableEventWatcher
397 // 4. WaitableEventWatcher callback should run (from #2)
398
399 WaitableEventWatcher::EventCallback watcher_callback = BindOnce(
400 [](bool* did_callback, WaitableEvent*) {
401 *did_callback = true;
402 },
403 Unretained(&did_callback));
404
405 task_runner->PostTask(
406 FROM_HERE, BindOnce(IgnoreResult(&WaitableEventWatcher::StartWatching),
407 Unretained(watcher.get()), Unretained(&event),
Hajime Hoshi138652c92018-01-12 15:11:44408 std::move(watcher_callback), task_runner));
Robert Sesek6d38e782017-07-13 00:46:50409 task_runner->PostTask(FROM_HERE,
410 BindOnce(&WaitableEvent::Signal, Unretained(&event)));
411 task_runner->DeleteSoon(FROM_HERE, std::move(watcher));
412 if (delay_after_delete) {
413 task_runner->PostTask(FROM_HERE, BindOnce(&PlatformThread::Sleep,
414 TimeDelta::FromMilliseconds(30)));
415 }
416
417 RunLoop().RunUntilIdle();
418
419 EXPECT_FALSE(did_callback);
420}
421
Victor Costan033b9ac2019-01-29 00:52:16422INSTANTIATE_TEST_SUITE_P(,
423 WaitableEventWatcherTest,
424 testing::ValuesIn(testing_main_threads));
[email protected]b57d33c52009-01-15 22:58:53425
Victor Costan033b9ac2019-01-29 00:52:16426INSTANTIATE_TEST_SUITE_P(
Robert Sesek3b3333772017-06-30 18:21:56427 ,
428 WaitableEventWatcherDeletionTest,
Sami Kyostila3f49cb572018-11-19 13:01:09429 testing::Combine(testing::ValuesIn(testing_main_threads), testing::Bool()));
[email protected]44f9c952011-01-02 06:05:39430
431} // namespace base