OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/synchronization/waitable_event_watcher.h" | 5 #include "base/synchronization/waitable_event_watcher.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/memory/ptr_util.h" | |
10 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
11 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
12 #include "base/synchronization/waitable_event.h" | 13 #include "base/synchronization/waitable_event.h" |
13 #include "base/threading/platform_thread.h" | 14 #include "base/threading/platform_thread.h" |
15 #include "base/threading/sequenced_task_runner_handle.h" | |
14 #include "build/build_config.h" | 16 #include "build/build_config.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
16 | 18 |
17 namespace base { | 19 namespace base { |
18 | 20 |
19 namespace { | 21 namespace { |
20 | 22 |
21 // The message loops on which each waitable event timer should be tested. | 23 // The message loops on which each waitable event timer should be tested. |
22 const MessageLoop::Type testing_message_loops[] = { | 24 const MessageLoop::Type testing_message_loops[] = { |
23 MessageLoop::TYPE_DEFAULT, | 25 MessageLoop::TYPE_DEFAULT, |
24 MessageLoop::TYPE_IO, | 26 MessageLoop::TYPE_IO, |
25 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop. | 27 #if !defined(OS_IOS) // iOS does not allow direct running of the UI loop. |
26 MessageLoop::TYPE_UI, | 28 MessageLoop::TYPE_UI, |
27 #endif | 29 #endif |
28 }; | 30 }; |
29 | 31 |
30 const int kNumTestingMessageLoops = arraysize(testing_message_loops); | 32 const int kNumTestingMessageLoops = arraysize(testing_message_loops); |
31 | 33 |
32 void QuitWhenSignaled(WaitableEvent* event) { | 34 void QuitWhenSignaled(WaitableEvent* event) { |
33 MessageLoop::current()->QuitWhenIdle(); | 35 MessageLoop::current()->QuitWhenIdle(); |
34 } | 36 } |
35 | 37 |
36 class DecrementCountContainer { | 38 class DecrementCountContainer { |
37 public: | 39 public: |
38 explicit DecrementCountContainer(int* counter) : counter_(counter) { | 40 explicit DecrementCountContainer(int* counter) : counter_(counter) { |
39 } | 41 } |
40 void OnWaitableEventSignaled(WaitableEvent* object) { | 42 void OnWaitableEventSignaled(WaitableEvent* object) { |
43 // NOTE: |object| may be already deleted. | |
41 --(*counter_); | 44 --(*counter_); |
42 } | 45 } |
43 private: | 46 private: |
44 int* counter_; | 47 int* counter_; |
45 }; | 48 }; |
46 | 49 |
47 void RunTest_BasicSignal(MessageLoop::Type message_loop_type) { | 50 void RunTest_BasicSignal(MessageLoop::Type message_loop_type) { |
48 MessageLoop message_loop(message_loop_type); | 51 MessageLoop message_loop(message_loop_type); |
49 | 52 |
50 // A manual-reset event that is not yet signaled. | 53 // A manual-reset event that is not yet signaled. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 { | 113 { |
111 WaitableEventWatcher watcher; | 114 WaitableEventWatcher watcher; |
112 { | 115 { |
113 MessageLoop message_loop(message_loop_type); | 116 MessageLoop message_loop(message_loop_type); |
114 | 117 |
115 watcher.StartWatching(&event, BindOnce(&QuitWhenSignaled)); | 118 watcher.StartWatching(&event, BindOnce(&QuitWhenSignaled)); |
116 } | 119 } |
117 } | 120 } |
118 } | 121 } |
119 | 122 |
120 void RunTest_DeleteUnder(MessageLoop::Type message_loop_type) { | 123 void RunTest_DeleteUnder(MessageLoop::Type message_loop_type, |
124 bool deferred_watcher_deletion) { | |
121 // Delete the WaitableEvent out from under the Watcher. This is explictly | 125 // Delete the WaitableEvent out from under the Watcher. This is explictly |
122 // allowed by the interface. | 126 // allowed by the interface. |
127 // If |deferred_watcher_deletion| is false the watcher will be deleted right | |
128 // after deleting the event, which leads to immediately cancelling the wait | |
129 // operation. | |
130 // If |deferred_watcher_deletion| is true the watcher will be deleted | |
131 // in another callstack. That checks that the watcher can live with a deleted | |
132 // event when watching is still in progress. | |
123 | 133 |
124 MessageLoop message_loop(message_loop_type); | 134 MessageLoop message_loop(message_loop_type); |
125 | 135 |
126 { | 136 { |
127 WaitableEventWatcher watcher; | 137 auto watcher = base::MakeUnique<WaitableEventWatcher>(); |
128 | 138 |
129 WaitableEvent* event = | 139 auto event = base::MakeUnique<WaitableEvent>( |
130 new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC, | 140 WaitableEvent::ResetPolicy::AUTOMATIC, |
131 WaitableEvent::InitialState::NOT_SIGNALED); | 141 WaitableEvent::InitialState::NOT_SIGNALED); |
132 | 142 |
133 watcher.StartWatching(event, BindOnce(&QuitWhenSignaled)); | 143 watcher->StartWatching(event.get(), BindOnce(&QuitWhenSignaled)); |
134 delete event; | 144 event.reset(); |
145 if (deferred_watcher_deletion) { | |
146 base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, | |
147 watcher.release()); | |
148 } | |
135 } | 149 } |
danakj
2017/05/04 16:09:37
What if you RunLoop().Run() here to let the watche
| |
136 } | 150 } |
137 | 151 |
152 void RunTest_SignalAndDelete(MessageLoop::Type message_loop_type, | |
153 bool deferred_watcher_deletion) { | |
154 // Signal and immediately delete the WaitableEvent out from under the Watcher. | |
155 // If |deferred_watcher_deletion| is false the watcher will be deleted right | |
156 // after deleting the event, which leads to immediately cancelling the wait | |
157 // operation. | |
158 // If |deferred_watcher_deletion| is true the watcher will be deleted | |
159 // in another callstack. That checks that the watcher can live with a deleted | |
160 // event when watching is still in progress. | |
161 | |
162 MessageLoop message_loop(message_loop_type); | |
163 | |
164 { | |
165 auto watcher = base::MakeUnique<WaitableEventWatcher>(); | |
166 | |
167 auto event = base::MakeUnique<WaitableEvent>( | |
168 WaitableEvent::ResetPolicy::AUTOMATIC, | |
169 WaitableEvent::InitialState::NOT_SIGNALED); | |
170 | |
171 watcher->StartWatching(event.get(), BindOnce(&QuitWhenSignaled)); | |
172 event->Signal(); | |
173 event.reset(); | |
174 if (deferred_watcher_deletion) { | |
175 base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, | |
176 watcher.release()); | |
177 } | |
178 } | |
179 } | |
180 | |
138 } // namespace | 181 } // namespace |
139 | 182 |
140 //----------------------------------------------------------------------------- | 183 //----------------------------------------------------------------------------- |
141 | 184 |
142 TEST(WaitableEventWatcherTest, BasicSignal) { | 185 TEST(WaitableEventWatcherTest, BasicSignal) { |
143 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 186 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
144 RunTest_BasicSignal(testing_message_loops[i]); | 187 RunTest_BasicSignal(testing_message_loops[i]); |
145 } | 188 } |
146 } | 189 } |
147 | 190 |
(...skipping 10 matching lines...) Expand all Loading... | |
158 } | 201 } |
159 | 202 |
160 TEST(WaitableEventWatcherTest, OutlivesMessageLoop) { | 203 TEST(WaitableEventWatcherTest, OutlivesMessageLoop) { |
161 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 204 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
162 RunTest_OutlivesMessageLoop(testing_message_loops[i]); | 205 RunTest_OutlivesMessageLoop(testing_message_loops[i]); |
163 } | 206 } |
164 } | 207 } |
165 | 208 |
166 TEST(WaitableEventWatcherTest, DeleteUnder) { | 209 TEST(WaitableEventWatcherTest, DeleteUnder) { |
167 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 210 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
168 RunTest_DeleteUnder(testing_message_loops[i]); | 211 RunTest_DeleteUnder(testing_message_loops[i], false); |
212 RunTest_DeleteUnder(testing_message_loops[i], true); | |
169 } | 213 } |
170 } | 214 } |
171 | 215 |
216 TEST(WaitableEventWatcherTest, SignalAndDelete) { | |
217 for (int i = 0; i < kNumTestingMessageLoops; i++) { | |
218 RunTest_SignalAndDelete(testing_message_loops[i], false); | |
219 RunTest_SignalAndDelete(testing_message_loops[i], true); | |
220 } | |
221 } | |
222 | |
172 } // namespace base | 223 } // namespace base |
OLD | NEW |