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