blob: 713ecb8e544de5add714b02f45a84852d2b2f610 [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]495cad92013-07-18 08:12:4011#include "base/message_loop/message_loop.h"
[email protected]f7b98b32013-02-05 08:14:1512#include "base/run_loop.h"
[email protected]44f9c952011-01-02 06:05:3913#include "base/synchronization/waitable_event.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"
avi9b6f42932015-12-26 22:15:1416#include "build/build_config.h"
[email protected]1c4947f2009-01-15 22:25:1117#include "testing/gtest/include/gtest/gtest.h"
18
[email protected]44f9c952011-01-02 06:05:3919namespace base {
[email protected]1c4947f2009-01-15 22:25:1120
21namespace {
22
[email protected]840246b2012-07-18 08:06:5023// The message loops on which each waitable event timer should be tested.
24const MessageLoop::Type testing_message_loops[] = {
25 MessageLoop::TYPE_DEFAULT,
26 MessageLoop::TYPE_IO,
27#if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
28 MessageLoop::TYPE_UI,
29#endif
30};
31
32const int kNumTestingMessageLoops = arraysize(testing_message_loops);
33
[email protected]329be052013-02-04 18:14:2834void QuitWhenSignaled(WaitableEvent* event) {
35 MessageLoop::current()->QuitWhenIdle();
36}
[email protected]1eaa54792013-01-31 23:14:2737
[email protected]329be052013-02-04 18:14:2838class DecrementCountContainer {
[email protected]1eaa54792013-01-31 23:14:2739 public:
[email protected]329be052013-02-04 18:14:2840 explicit DecrementCountContainer(int* counter) : counter_(counter) {
[email protected]1eaa54792013-01-31 23:14:2741 }
[email protected]329be052013-02-04 18:14:2842 void OnWaitableEventSignaled(WaitableEvent* object) {
atuchin54d83152017-05-10 06:30:0143 // NOTE: |object| may be already deleted.
[email protected]1c4947f2009-01-15 22:25:1144 --(*counter_);
45 }
46 private:
47 int* counter_;
48};
49
[email protected]1c4947f2009-01-15 22:25:1150void RunTest_BasicSignal(MessageLoop::Type message_loop_type) {
51 MessageLoop message_loop(message_loop_type);
52
53 // A manual-reset event that is not yet signaled.
gab75d72332016-06-01 21:15:3354 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
55 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]1c4947f2009-01-15 22:25:1156
57 WaitableEventWatcher watcher;
tzik130cfd0c2017-04-18 03:49:0558 watcher.StartWatching(&event, BindOnce(&QuitWhenSignaled));
[email protected]1c4947f2009-01-15 22:25:1159
60 event.Signal();
61
fdoray10224582016-06-30 18:17:3962 RunLoop().Run();
[email protected]1c4947f2009-01-15 22:25:1163}
64
65void RunTest_BasicCancel(MessageLoop::Type message_loop_type) {
66 MessageLoop message_loop(message_loop_type);
67
68 // A manual-reset event that is not yet signaled.
gab75d72332016-06-01 21:15:3369 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
70 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]1c4947f2009-01-15 22:25:1171
72 WaitableEventWatcher watcher;
73
tzik130cfd0c2017-04-18 03:49:0574 watcher.StartWatching(&event, BindOnce(&QuitWhenSignaled));
[email protected]1c4947f2009-01-15 22:25:1175
76 watcher.StopWatching();
77}
78
79void RunTest_CancelAfterSet(MessageLoop::Type message_loop_type) {
80 MessageLoop message_loop(message_loop_type);
81
82 // A manual-reset event that is not yet signaled.
gab75d72332016-06-01 21:15:3383 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
84 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]1c4947f2009-01-15 22:25:1185
86 WaitableEventWatcher watcher;
87
88 int counter = 1;
[email protected]329be052013-02-04 18:14:2889 DecrementCountContainer delegate(&counter);
tzik130cfd0c2017-04-18 03:49:0590 WaitableEventWatcher::EventCallback callback = BindOnce(
91 &DecrementCountContainer::OnWaitableEventSignaled, Unretained(&delegate));
92 watcher.StartWatching(&event, std::move(callback));
[email protected]1c4947f2009-01-15 22:25:1193
94 event.Signal();
95
96 // Let the background thread do its business
[email protected]a1b75b942011-12-31 22:53:5197 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30));
[email protected]1c4947f2009-01-15 22:25:1198
99 watcher.StopWatching();
100
[email protected]f7b98b32013-02-05 08:14:15101 RunLoop().RunUntilIdle();
[email protected]1c4947f2009-01-15 22:25:11102
103 // Our delegate should not have fired.
104 EXPECT_EQ(1, counter);
105}
106
107void RunTest_OutlivesMessageLoop(MessageLoop::Type message_loop_type) {
108 // Simulate a MessageLoop that dies before an WaitableEventWatcher. This
109 // ordinarily doesn't happen when people use the Thread class, but it can
110 // happen when people use the Singleton pattern or atexit.
gab75d72332016-06-01 21:15:33111 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
112 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]1c4947f2009-01-15 22:25:11113 {
114 WaitableEventWatcher watcher;
115 {
116 MessageLoop message_loop(message_loop_type);
117
tzik130cfd0c2017-04-18 03:49:05118 watcher.StartWatching(&event, BindOnce(&QuitWhenSignaled));
[email protected]1c4947f2009-01-15 22:25:11119 }
120 }
121}
122
atuchin54d83152017-05-10 06:30:01123void RunTest_DeleteUnder(MessageLoop::Type message_loop_type,
124 bool delay_after_delete) {
[email protected]c891ab92009-03-26 18:28:19125 // Delete the WaitableEvent out from under the Watcher. This is explictly
126 // allowed by the interface.
127
128 MessageLoop message_loop(message_loop_type);
129
130 {
131 WaitableEventWatcher watcher;
132
atuchin54d83152017-05-10 06:30:01133 auto* event = new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC,
134 WaitableEvent::InitialState::NOT_SIGNALED);
[email protected]329be052013-02-04 18:14:28135
tzik130cfd0c2017-04-18 03:49:05136 watcher.StartWatching(event, BindOnce(&QuitWhenSignaled));
atuchin54d83152017-05-10 06:30:01137
138 if (delay_after_delete) {
139 // On Windows that sleep() improves the chance to catch some problems.
140 // It postpones the dtor |watcher| (which immediately cancel the waiting)
141 // and gives some time to run to a created background thread.
142 // Unfortunately, that thread is under OS control and we can't
143 // manipulate it directly.
144 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30));
145 }
146
[email protected]c891ab92009-03-26 18:28:19147 delete event;
148 }
149}
150
atuchin54d83152017-05-10 06:30:01151void RunTest_SignalAndDelete(MessageLoop::Type message_loop_type,
152 bool delay_after_delete) {
153 // Signal and immediately delete the WaitableEvent out from under the Watcher.
154
155 MessageLoop message_loop(message_loop_type);
156
157 {
158 WaitableEventWatcher watcher;
159
160 auto event = base::MakeUnique<WaitableEvent>(
161 WaitableEvent::ResetPolicy::AUTOMATIC,
162 WaitableEvent::InitialState::NOT_SIGNALED);
163
164 watcher.StartWatching(event.get(), BindOnce(&QuitWhenSignaled));
165 event->Signal();
166 event.reset();
167
168 if (delay_after_delete) {
169 // On Windows that sleep() improves the chance to catch some problems.
170 // It postpones the dtor |watcher| (which immediately cancel the waiting)
171 // and gives some time to run to a created background thread.
172 // Unfortunately, that thread is under OS control and we can't
173 // manipulate it directly.
174 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30));
175 }
176
177 // Wait for the watcher callback.
178 RunLoop().Run();
179 }
180}
181
[email protected]b57d33c52009-01-15 22:58:53182} // namespace
183
[email protected]1c4947f2009-01-15 22:25:11184//-----------------------------------------------------------------------------
185
[email protected]9480d2ab2009-01-15 22:52:38186TEST(WaitableEventWatcherTest, BasicSignal) {
[email protected]840246b2012-07-18 08:06:50187 for (int i = 0; i < kNumTestingMessageLoops; i++) {
188 RunTest_BasicSignal(testing_message_loops[i]);
189 }
[email protected]1c4947f2009-01-15 22:25:11190}
191
[email protected]9480d2ab2009-01-15 22:52:38192TEST(WaitableEventWatcherTest, BasicCancel) {
[email protected]840246b2012-07-18 08:06:50193 for (int i = 0; i < kNumTestingMessageLoops; i++) {
194 RunTest_BasicCancel(testing_message_loops[i]);
195 }
[email protected]1c4947f2009-01-15 22:25:11196}
197
[email protected]9480d2ab2009-01-15 22:52:38198TEST(WaitableEventWatcherTest, CancelAfterSet) {
[email protected]840246b2012-07-18 08:06:50199 for (int i = 0; i < kNumTestingMessageLoops; i++) {
200 RunTest_CancelAfterSet(testing_message_loops[i]);
201 }
[email protected]1c4947f2009-01-15 22:25:11202}
203
[email protected]9480d2ab2009-01-15 22:52:38204TEST(WaitableEventWatcherTest, OutlivesMessageLoop) {
[email protected]840246b2012-07-18 08:06:50205 for (int i = 0; i < kNumTestingMessageLoops; i++) {
206 RunTest_OutlivesMessageLoop(testing_message_loops[i]);
207 }
[email protected]1c4947f2009-01-15 22:25:11208}
[email protected]c891ab92009-03-26 18:28:19209
mattm5cc71c0e2016-07-06 23:56:26210TEST(WaitableEventWatcherTest, DeleteUnder) {
[email protected]840246b2012-07-18 08:06:50211 for (int i = 0; i < kNumTestingMessageLoops; i++) {
atuchin54d83152017-05-10 06:30:01212 RunTest_DeleteUnder(testing_message_loops[i], false);
213 RunTest_DeleteUnder(testing_message_loops[i], true);
214 }
215}
216
217TEST(WaitableEventWatcherTest, SignalAndDelete) {
218 for (int i = 0; i < kNumTestingMessageLoops; i++) {
219 RunTest_SignalAndDelete(testing_message_loops[i], false);
220 RunTest_SignalAndDelete(testing_message_loops[i], true);
[email protected]840246b2012-07-18 08:06:50221 }
[email protected]c891ab92009-03-26 18:28:19222}
[email protected]44f9c952011-01-02 06:05:39223
224} // namespace base