• 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 <process.h>
6 
7 #include "base/message_loop.h"
8 #include "base/win/object_watcher.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 
11 namespace base {
12 namespace win {
13 
14 namespace {
15 
16 class QuitDelegate : public ObjectWatcher::Delegate {
17  public:
OnObjectSignaled(HANDLE object)18   virtual void OnObjectSignaled(HANDLE object) {
19     MessageLoop::current()->Quit();
20   }
21 };
22 
23 class DecrementCountDelegate : public ObjectWatcher::Delegate {
24  public:
DecrementCountDelegate(int * counter)25   explicit DecrementCountDelegate(int* counter) : counter_(counter) {
26   }
OnObjectSignaled(HANDLE object)27   virtual void OnObjectSignaled(HANDLE 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   ObjectWatcher watcher;
38   EXPECT_EQ(NULL, watcher.GetWatchedObject());
39 
40   // A manual-reset event that is not yet signaled.
41   HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);
42 
43   QuitDelegate delegate;
44   bool ok = watcher.StartWatching(event, &delegate);
45   EXPECT_TRUE(ok);
46   EXPECT_EQ(event, watcher.GetWatchedObject());
47 
48   SetEvent(event);
49 
50   MessageLoop::current()->Run();
51 
52   EXPECT_EQ(NULL, watcher.GetWatchedObject());
53   CloseHandle(event);
54 }
55 
RunTest_BasicCancel(MessageLoop::Type message_loop_type)56 void RunTest_BasicCancel(MessageLoop::Type message_loop_type) {
57   MessageLoop message_loop(message_loop_type);
58 
59   ObjectWatcher watcher;
60 
61   // A manual-reset event that is not yet signaled.
62   HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);
63 
64   QuitDelegate delegate;
65   bool ok = watcher.StartWatching(event, &delegate);
66   EXPECT_TRUE(ok);
67 
68   watcher.StopWatching();
69 
70   CloseHandle(event);
71 }
72 
73 
RunTest_CancelAfterSet(MessageLoop::Type message_loop_type)74 void RunTest_CancelAfterSet(MessageLoop::Type message_loop_type) {
75   MessageLoop message_loop(message_loop_type);
76 
77   ObjectWatcher watcher;
78 
79   int counter = 1;
80   DecrementCountDelegate delegate(&counter);
81 
82     // A manual-reset event that is not yet signaled.
83   HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);
84 
85   bool ok = watcher.StartWatching(event, &delegate);
86   EXPECT_TRUE(ok);
87 
88   SetEvent(event);
89 
90   // Let the background thread do its business
91   Sleep(30);
92 
93   watcher.StopWatching();
94 
95   MessageLoop::current()->RunAllPending();
96 
97   // Our delegate should not have fired.
98   EXPECT_EQ(1, counter);
99 
100   CloseHandle(event);
101 }
102 
RunTest_OutlivesMessageLoop(MessageLoop::Type message_loop_type)103 void RunTest_OutlivesMessageLoop(MessageLoop::Type message_loop_type) {
104   // Simulate a MessageLoop that dies before an ObjectWatcher.  This ordinarily
105   // doesn't happen when people use the Thread class, but it can happen when
106   // people use the Singleton pattern or atexit.
107   HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL);  // not signaled
108   {
109     ObjectWatcher watcher;
110     {
111       MessageLoop message_loop(message_loop_type);
112 
113       QuitDelegate delegate;
114       watcher.StartWatching(event, &delegate);
115     }
116   }
117   CloseHandle(event);
118 }
119 
120 }  // namespace
121 
122 //-----------------------------------------------------------------------------
123 
TEST(ObjectWatcherTest,BasicSignal)124 TEST(ObjectWatcherTest, BasicSignal) {
125   RunTest_BasicSignal(MessageLoop::TYPE_DEFAULT);
126   RunTest_BasicSignal(MessageLoop::TYPE_IO);
127   RunTest_BasicSignal(MessageLoop::TYPE_UI);
128 }
129 
TEST(ObjectWatcherTest,BasicCancel)130 TEST(ObjectWatcherTest, BasicCancel) {
131   RunTest_BasicCancel(MessageLoop::TYPE_DEFAULT);
132   RunTest_BasicCancel(MessageLoop::TYPE_IO);
133   RunTest_BasicCancel(MessageLoop::TYPE_UI);
134 }
135 
TEST(ObjectWatcherTest,CancelAfterSet)136 TEST(ObjectWatcherTest, CancelAfterSet) {
137   RunTest_CancelAfterSet(MessageLoop::TYPE_DEFAULT);
138   RunTest_CancelAfterSet(MessageLoop::TYPE_IO);
139   RunTest_CancelAfterSet(MessageLoop::TYPE_UI);
140 }
141 
TEST(ObjectWatcherTest,OutlivesMessageLoop)142 TEST(ObjectWatcherTest, OutlivesMessageLoop) {
143   RunTest_OutlivesMessageLoop(MessageLoop::TYPE_DEFAULT);
144   RunTest_OutlivesMessageLoop(MessageLoop::TYPE_IO);
145   RunTest_OutlivesMessageLoop(MessageLoop::TYPE_UI);
146 }
147 
148 }  // namespace win
149 }  // namespace base
150