OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/message_loop.h" | |
6 #include "base/threading/platform_thread.h" | |
7 #include "base/waitable_event.h" | |
8 #include "base/waitable_event_watcher.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | |
10 | |
11 using base::WaitableEvent; | |
12 using base::WaitableEventWatcher; | |
13 | |
14 namespace { | |
15 | |
16 class QuitDelegate : public WaitableEventWatcher::Delegate { | |
17 public: | |
18 virtual void OnWaitableEventSignaled(WaitableEvent* event) { | |
19 MessageLoop::current()->Quit(); | |
20 } | |
21 }; | |
22 | |
23 class DecrementCountDelegate : public WaitableEventWatcher::Delegate { | |
24 public: | |
25 explicit DecrementCountDelegate(int* counter) : counter_(counter) { | |
26 } | |
27 virtual void OnWaitableEventSignaled(WaitableEvent* object) { | |
28 --(*counter_); | |
29 } | |
30 private: | |
31 int* counter_; | |
32 }; | |
33 | |
34 void RunTest_BasicSignal(MessageLoop::Type message_loop_type) { | |
35 MessageLoop message_loop(message_loop_type); | |
36 | |
37 // A manual-reset event that is not yet signaled. | |
38 WaitableEvent event(true, false); | |
39 | |
40 WaitableEventWatcher watcher; | |
41 EXPECT_TRUE(watcher.GetWatchedEvent() == NULL); | |
42 | |
43 QuitDelegate delegate; | |
44 watcher.StartWatching(&event, &delegate); | |
45 EXPECT_EQ(&event, watcher.GetWatchedEvent()); | |
46 | |
47 event.Signal(); | |
48 | |
49 MessageLoop::current()->Run(); | |
50 | |
51 EXPECT_TRUE(watcher.GetWatchedEvent() == NULL); | |
52 } | |
53 | |
54 void RunTest_BasicCancel(MessageLoop::Type message_loop_type) { | |
55 MessageLoop message_loop(message_loop_type); | |
56 | |
57 // A manual-reset event that is not yet signaled. | |
58 WaitableEvent event(true, false); | |
59 | |
60 WaitableEventWatcher watcher; | |
61 | |
62 QuitDelegate delegate; | |
63 watcher.StartWatching(&event, &delegate); | |
64 | |
65 watcher.StopWatching(); | |
66 } | |
67 | |
68 void RunTest_CancelAfterSet(MessageLoop::Type message_loop_type) { | |
69 MessageLoop message_loop(message_loop_type); | |
70 | |
71 // A manual-reset event that is not yet signaled. | |
72 WaitableEvent event(true, false); | |
73 | |
74 WaitableEventWatcher watcher; | |
75 | |
76 int counter = 1; | |
77 DecrementCountDelegate delegate(&counter); | |
78 | |
79 watcher.StartWatching(&event, &delegate); | |
80 | |
81 event.Signal(); | |
82 | |
83 // Let the background thread do its business | |
84 base::PlatformThread::Sleep(30); | |
85 | |
86 watcher.StopWatching(); | |
87 | |
88 MessageLoop::current()->RunAllPending(); | |
89 | |
90 // Our delegate should not have fired. | |
91 EXPECT_EQ(1, counter); | |
92 } | |
93 | |
94 void RunTest_OutlivesMessageLoop(MessageLoop::Type message_loop_type) { | |
95 // Simulate a MessageLoop that dies before an WaitableEventWatcher. This | |
96 // ordinarily doesn't happen when people use the Thread class, but it can | |
97 // happen when people use the Singleton pattern or atexit. | |
98 WaitableEvent event(true, false); | |
99 { | |
100 WaitableEventWatcher watcher; | |
101 { | |
102 MessageLoop message_loop(message_loop_type); | |
103 | |
104 QuitDelegate delegate; | |
105 watcher.StartWatching(&event, &delegate); | |
106 } | |
107 } | |
108 } | |
109 | |
110 void RunTest_DeleteUnder(MessageLoop::Type message_loop_type) { | |
111 // Delete the WaitableEvent out from under the Watcher. This is explictly | |
112 // allowed by the interface. | |
113 | |
114 MessageLoop message_loop(message_loop_type); | |
115 | |
116 { | |
117 WaitableEventWatcher watcher; | |
118 | |
119 WaitableEvent* event = new WaitableEvent(false, false); | |
120 QuitDelegate delegate; | |
121 watcher.StartWatching(event, &delegate); | |
122 delete event; | |
123 } | |
124 } | |
125 | |
126 } // namespace | |
127 | |
128 //----------------------------------------------------------------------------- | |
129 | |
130 TEST(WaitableEventWatcherTest, BasicSignal) { | |
131 RunTest_BasicSignal(MessageLoop::TYPE_DEFAULT); | |
132 RunTest_BasicSignal(MessageLoop::TYPE_IO); | |
133 RunTest_BasicSignal(MessageLoop::TYPE_UI); | |
134 } | |
135 | |
136 TEST(WaitableEventWatcherTest, BasicCancel) { | |
137 RunTest_BasicCancel(MessageLoop::TYPE_DEFAULT); | |
138 RunTest_BasicCancel(MessageLoop::TYPE_IO); | |
139 RunTest_BasicCancel(MessageLoop::TYPE_UI); | |
140 } | |
141 | |
142 TEST(WaitableEventWatcherTest, CancelAfterSet) { | |
143 RunTest_CancelAfterSet(MessageLoop::TYPE_DEFAULT); | |
144 RunTest_CancelAfterSet(MessageLoop::TYPE_IO); | |
145 RunTest_CancelAfterSet(MessageLoop::TYPE_UI); | |
146 } | |
147 | |
148 TEST(WaitableEventWatcherTest, OutlivesMessageLoop) { | |
149 RunTest_OutlivesMessageLoop(MessageLoop::TYPE_DEFAULT); | |
150 RunTest_OutlivesMessageLoop(MessageLoop::TYPE_IO); | |
151 RunTest_OutlivesMessageLoop(MessageLoop::TYPE_UI); | |
152 } | |
153 | |
154 #if defined(OS_WIN) | |
155 // Crashes sometimes on vista. http://crbug.com/62119 | |
156 #define MAYBE_DeleteUnder DISABLED_DeleteUnder | |
157 #else | |
158 #define MAYBE_DeleteUnder DeleteUnder | |
159 #endif | |
160 TEST(WaitableEventWatcherTest, MAYBE_DeleteUnder) { | |
161 RunTest_DeleteUnder(MessageLoop::TYPE_DEFAULT); | |
162 RunTest_DeleteUnder(MessageLoop::TYPE_IO); | |
163 RunTest_DeleteUnder(MessageLoop::TYPE_UI); | |
164 } | |
OLD | NEW |