Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: base/synchronization/waitable_event_watcher_unittest.cc

Issue 2839213002: [Synchronization] Fix a crash in WaitableEventWatcher (Closed)
Patch Set: Rewrite some comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 false the watcher will be deleted right
danakj 2017/05/03 14:50:03 deletion
128 // after deleting the event, which leads to immediately cancel the wait
danakj 2017/05/03 14:50:03 cancelling
129 // operation.
130 // If |deferred_watcher_delete| is true the watcher will be deleted
danakj 2017/05/03 14:50:03 deletion
131 // in another callstack. That checks that the watcher can live with deleted
danakj 2017/05/03 14:50:03 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 }
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_delete| is true the watcher will be deleted in another
danakj 2017/05/03 14:50:03 this sentence is a duplicate from below
156 // callstack.
157 // If |deferred_watcher_delete| is false the watcher will be deleted right
danakj 2017/05/03 14:50:03 deletion
158 // after deleting the event, which leads to immediately cancel the wait
danakj 2017/05/03 14:50:03 cancelling
159 // operation.
160 // If |deferred_watcher_delete| is true the watcher will be deleted
danakj 2017/05/03 14:50:03 deletion
161 // in another callstack. That checks that the watcher can live with deleted
danakj 2017/05/03 14:50:03 with a deleted
162 // event when watching is still in progress.
163
164 MessageLoop message_loop(message_loop_type);
165
166 {
167 auto watcher = base::MakeUnique<WaitableEventWatcher>();
168
169 auto event = base::MakeUnique<WaitableEvent>(
170 WaitableEvent::ResetPolicy::AUTOMATIC,
171 WaitableEvent::InitialState::NOT_SIGNALED);
172
173 watcher->StartWatching(event.get(), BindOnce(&QuitWhenSignaled));
174 event->Signal();
175 event.reset();
176 if (deferred_watcher_deletion) {
177 base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
178 watcher.release());
179 }
180 }
181 }
182
138 } // namespace 183 } // namespace
139 184
140 //----------------------------------------------------------------------------- 185 //-----------------------------------------------------------------------------
141 186
142 TEST(WaitableEventWatcherTest, BasicSignal) { 187 TEST(WaitableEventWatcherTest, BasicSignal) {
143 for (int i = 0; i < kNumTestingMessageLoops; i++) { 188 for (int i = 0; i < kNumTestingMessageLoops; i++) {
144 RunTest_BasicSignal(testing_message_loops[i]); 189 RunTest_BasicSignal(testing_message_loops[i]);
145 } 190 }
146 } 191 }
147 192
(...skipping 10 matching lines...) Expand all
158 } 203 }
159 204
160 TEST(WaitableEventWatcherTest, OutlivesMessageLoop) { 205 TEST(WaitableEventWatcherTest, OutlivesMessageLoop) {
161 for (int i = 0; i < kNumTestingMessageLoops; i++) { 206 for (int i = 0; i < kNumTestingMessageLoops; i++) {
162 RunTest_OutlivesMessageLoop(testing_message_loops[i]); 207 RunTest_OutlivesMessageLoop(testing_message_loops[i]);
163 } 208 }
164 } 209 }
165 210
166 TEST(WaitableEventWatcherTest, DeleteUnder) { 211 TEST(WaitableEventWatcherTest, DeleteUnder) {
167 for (int i = 0; i < kNumTestingMessageLoops; i++) { 212 for (int i = 0; i < kNumTestingMessageLoops; i++) {
168 RunTest_DeleteUnder(testing_message_loops[i]); 213 RunTest_DeleteUnder(testing_message_loops[i], false);
214 RunTest_DeleteUnder(testing_message_loops[i], true);
169 } 215 }
170 } 216 }
171 217
218 TEST(WaitableEventWatcherTest, SignalAndDelete) {
219 for (int i = 0; i < kNumTestingMessageLoops; i++) {
220 RunTest_SignalAndDelete(testing_message_loops[i], false);
221 RunTest_SignalAndDelete(testing_message_loops[i], true);
222 }
223 }
224
172 } // namespace base 225 } // namespace base
OLDNEW
« no previous file with comments | « base/synchronization/waitable_event_watcher.h ('k') | base/synchronization/waitable_event_watcher_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698