Chromium Code Reviews| 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/thread_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_delete| is true the watcher will be deleted in another | |
| 128 // callstack. (Calling the dtor can make a difference for the behavior | |
| 129 // of the test) | |
|
danakj
2017/05/02 14:46:22
nit: .
atuchin
2017/05/03 13:01:58
Done.
| |
| 123 | 130 |
| 124 MessageLoop message_loop(message_loop_type); | 131 MessageLoop message_loop(message_loop_type); |
| 125 | 132 |
| 126 { | 133 { |
| 127 WaitableEventWatcher watcher; | 134 auto watcher = base::MakeUnique<WaitableEventWatcher>(); |
| 128 | 135 |
| 129 WaitableEvent* event = | 136 auto event = base::MakeUnique<WaitableEvent>( |
| 130 new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC, | 137 WaitableEvent::ResetPolicy::AUTOMATIC, |
| 131 WaitableEvent::InitialState::NOT_SIGNALED); | 138 WaitableEvent::InitialState::NOT_SIGNALED); |
| 132 | 139 |
| 133 watcher.StartWatching(event, BindOnce(&QuitWhenSignaled)); | 140 watcher->StartWatching(event.get(), BindOnce(&QuitWhenSignaled)); |
| 134 delete event; | 141 event.reset(); |
| 142 if (deferred_watcher_deletion) { | |
| 143 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, | |
|
danakj
2017/05/02 14:46:22
nit: SequencedTaskRunnerHandle
atuchin
2017/05/03 13:01:58
Done.
| |
| 144 watcher.release()); | |
| 145 } | |
| 135 } | 146 } |
| 136 } | 147 } |
| 137 | 148 |
| 149 void RunTest_SignalAndDelete(MessageLoop::Type message_loop_type, | |
| 150 bool deferred_watcher_deletion) { | |
| 151 // Signal and immediately delete the WaitableEvent out from under the Watcher. | |
| 152 // If |deferred_watcher_delete| is true the watcher will be deleted in another | |
| 153 // callstack. (Calling the dtor can make a difference for the behavior | |
|
danakj
2017/05/02 14:46:21
It would be nice if you instead explained how it m
atuchin
2017/05/03 13:01:58
Ok, I rewrote the comment, trying to avoid platfor
danakj
2017/05/03 14:50:03
FWIW, IMO it's fine to say "On windows, ..." in a
| |
| 154 // of the test) | |
|
danakj
2017/05/02 14:46:22
nit: .
atuchin
2017/05/03 13:01:58
Done.
| |
| 155 | |
| 156 MessageLoop message_loop(message_loop_type); | |
| 157 | |
| 158 { | |
| 159 auto watcher = base::MakeUnique<WaitableEventWatcher>(); | |
| 160 | |
| 161 auto event = base::MakeUnique<WaitableEvent>( | |
| 162 WaitableEvent::ResetPolicy::AUTOMATIC, | |
| 163 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 164 | |
| 165 watcher->StartWatching(event.get(), BindOnce(&QuitWhenSignaled)); | |
| 166 event->Signal(); | |
| 167 event.reset(); | |
| 168 if (deferred_watcher_deletion) { | |
| 169 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, | |
|
danakj
2017/05/02 14:46:22
nit: SequencedTaskRunnerHandle
atuchin
2017/05/03 13:01:58
Done.
| |
| 170 watcher.release()); | |
| 171 } | |
| 172 } | |
| 173 } | |
| 174 | |
| 138 } // namespace | 175 } // namespace |
| 139 | 176 |
| 140 //----------------------------------------------------------------------------- | 177 //----------------------------------------------------------------------------- |
| 141 | 178 |
| 142 TEST(WaitableEventWatcherTest, BasicSignal) { | 179 TEST(WaitableEventWatcherTest, BasicSignal) { |
| 143 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 180 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
| 144 RunTest_BasicSignal(testing_message_loops[i]); | 181 RunTest_BasicSignal(testing_message_loops[i]); |
| 145 } | 182 } |
| 146 } | 183 } |
| 147 | 184 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 158 } | 195 } |
| 159 | 196 |
| 160 TEST(WaitableEventWatcherTest, OutlivesMessageLoop) { | 197 TEST(WaitableEventWatcherTest, OutlivesMessageLoop) { |
| 161 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 198 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
| 162 RunTest_OutlivesMessageLoop(testing_message_loops[i]); | 199 RunTest_OutlivesMessageLoop(testing_message_loops[i]); |
| 163 } | 200 } |
| 164 } | 201 } |
| 165 | 202 |
| 166 TEST(WaitableEventWatcherTest, DeleteUnder) { | 203 TEST(WaitableEventWatcherTest, DeleteUnder) { |
| 167 for (int i = 0; i < kNumTestingMessageLoops; i++) { | 204 for (int i = 0; i < kNumTestingMessageLoops; i++) { |
| 168 RunTest_DeleteUnder(testing_message_loops[i]); | 205 RunTest_DeleteUnder(testing_message_loops[i], false); |
| 206 RunTest_DeleteUnder(testing_message_loops[i], true); | |
| 169 } | 207 } |
| 170 } | 208 } |
| 171 | 209 |
| 210 TEST(WaitableEventWatcherTest, SignalAndDelete) { | |
| 211 for (int i = 0; i < kNumTestingMessageLoops; i++) { | |
| 212 RunTest_SignalAndDelete(testing_message_loops[i], false); | |
| 213 RunTest_SignalAndDelete(testing_message_loops[i], true); | |
| 214 } | |
| 215 } | |
| 216 | |
| 172 } // namespace base | 217 } // namespace base |
| OLD | NEW |