• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 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/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:
OnWaitableEventSignaled(WaitableEvent * event)18   virtual void OnWaitableEventSignaled(WaitableEvent* event) {
19     MessageLoop::current()->Quit();
20   }
21 };
22 
23 class DecrementCountDelegate : public WaitableEventWatcher::Delegate {
24  public:
DecrementCountDelegate(int * counter)25   explicit DecrementCountDelegate(int* counter) : counter_(counter) {
26   }
OnWaitableEventSignaled(WaitableEvent * object)27   virtual void OnWaitableEventSignaled(WaitableEvent* object) {
28     --(*counter_);
29   }
30  private:
31   int* counter_;
32 };
33 
RunTest_BasicSignal(MessageLoop::Type message_loop_type)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 
RunTest_BasicCancel(MessageLoop::Type message_loop_type)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 
RunTest_CancelAfterSet(MessageLoop::Type message_loop_type)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   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 
RunTest_OutlivesMessageLoop(MessageLoop::Type message_loop_type)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 
RunTest_DeleteUnder(MessageLoop::Type message_loop_type)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 
TEST(WaitableEventWatcherTest,BasicSignal)130 TEST(WaitableEventWatcherTest, BasicSignal) {
131   RunTest_BasicSignal(MessageLoop::TYPE_DEFAULT);
132   RunTest_BasicSignal(MessageLoop::TYPE_IO);
133   RunTest_BasicSignal(MessageLoop::TYPE_UI);
134 }
135 
TEST(WaitableEventWatcherTest,BasicCancel)136 TEST(WaitableEventWatcherTest, BasicCancel) {
137   RunTest_BasicCancel(MessageLoop::TYPE_DEFAULT);
138   RunTest_BasicCancel(MessageLoop::TYPE_IO);
139   RunTest_BasicCancel(MessageLoop::TYPE_UI);
140 }
141 
TEST(WaitableEventWatcherTest,CancelAfterSet)142 TEST(WaitableEventWatcherTest, CancelAfterSet) {
143   RunTest_CancelAfterSet(MessageLoop::TYPE_DEFAULT);
144   RunTest_CancelAfterSet(MessageLoop::TYPE_IO);
145   RunTest_CancelAfterSet(MessageLoop::TYPE_UI);
146 }
147 
TEST(WaitableEventWatcherTest,OutlivesMessageLoop)148 TEST(WaitableEventWatcherTest, OutlivesMessageLoop) {
149   RunTest_OutlivesMessageLoop(MessageLoop::TYPE_DEFAULT);
150   RunTest_OutlivesMessageLoop(MessageLoop::TYPE_IO);
151   RunTest_OutlivesMessageLoop(MessageLoop::TYPE_UI);
152 }
153 
TEST(WaitableEventWatcherTest,DeleteUnder)154 TEST(WaitableEventWatcherTest, DeleteUnder) {
155   RunTest_DeleteUnder(MessageLoop::TYPE_DEFAULT);
156   RunTest_DeleteUnder(MessageLoop::TYPE_IO);
157   RunTest_DeleteUnder(MessageLoop::TYPE_UI);
158 }
159