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