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: 18 virtual void OnObjectSignaled(HANDLE object) { 19 MessageLoop::current()->Quit(); 20 } 21 }; 22 23 class DecrementCountDelegate : public ObjectWatcher::Delegate { 24 public: 25 explicit DecrementCountDelegate(int* counter) : counter_(counter) { 26 } 27 virtual void OnObjectSignaled(HANDLE object) { 28 --(*counter_); 29 } 30 private: 31 int* counter_; 32 }; 33 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 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 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 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 124 TEST(ObjectWatcherTest, BasicSignal) { 125 RunTest_BasicSignal(MessageLoop::TYPE_DEFAULT); 126 RunTest_BasicSignal(MessageLoop::TYPE_IO); 127 RunTest_BasicSignal(MessageLoop::TYPE_UI); 128 } 129 130 TEST(ObjectWatcherTest, BasicCancel) { 131 RunTest_BasicCancel(MessageLoop::TYPE_DEFAULT); 132 RunTest_BasicCancel(MessageLoop::TYPE_IO); 133 RunTest_BasicCancel(MessageLoop::TYPE_UI); 134 } 135 136 TEST(ObjectWatcherTest, CancelAfterSet) { 137 RunTest_CancelAfterSet(MessageLoop::TYPE_DEFAULT); 138 RunTest_CancelAfterSet(MessageLoop::TYPE_IO); 139 RunTest_CancelAfterSet(MessageLoop::TYPE_UI); 140 } 141 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