Home | History | Annotate | Download | only in win
      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