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 11namespace base { 12namespace win { 13 14namespace { 15 16class QuitDelegate : public ObjectWatcher::Delegate { 17 public: 18 virtual void OnObjectSignaled(HANDLE object) { 19 MessageLoop::current()->Quit(); 20 } 21}; 22 23class 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 34void 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 56void 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 74void 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 103void 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 124TEST(ObjectWatcherTest, BasicSignal) { 125 RunTest_BasicSignal(MessageLoop::TYPE_DEFAULT); 126 RunTest_BasicSignal(MessageLoop::TYPE_IO); 127 RunTest_BasicSignal(MessageLoop::TYPE_UI); 128} 129 130TEST(ObjectWatcherTest, BasicCancel) { 131 RunTest_BasicCancel(MessageLoop::TYPE_DEFAULT); 132 RunTest_BasicCancel(MessageLoop::TYPE_IO); 133 RunTest_BasicCancel(MessageLoop::TYPE_UI); 134} 135 136TEST(ObjectWatcherTest, CancelAfterSet) { 137 RunTest_CancelAfterSet(MessageLoop::TYPE_DEFAULT); 138 RunTest_CancelAfterSet(MessageLoop::TYPE_IO); 139 RunTest_CancelAfterSet(MessageLoop::TYPE_UI); 140} 141 142TEST(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