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