waitable_event_watcher_unittest.cc revision 3f50c38dc070f4bb515c1b64450dae14f316474e
15ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 35ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen// found in the LICENSE file. 45ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 55ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "base/message_loop.h" 65ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "base/synchronization/waitable_event.h" 75ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "base/synchronization/waitable_event_watcher.h" 85ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "base/threading/platform_thread.h" 95ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "testing/gtest/include/gtest/gtest.h" 105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsennamespace base { 125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsennamespace { 145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenclass QuitDelegate : public WaitableEventWatcher::Delegate { 165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen public: 175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen virtual void OnWaitableEventSignaled(WaitableEvent* event) { 185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen MessageLoop::current()->Quit(); 195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}; 215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 225ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenclass DecrementCountDelegate : public WaitableEventWatcher::Delegate { 235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen public: 245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen explicit DecrementCountDelegate(int* counter) : counter_(counter) { 255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen virtual void OnWaitableEventSignaled(WaitableEvent* object) { 275ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen --(*counter_); 285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen } 295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen private: 305ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen int* counter_; 315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}; 325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid RunTest_BasicSignal(MessageLoop::Type message_loop_type) { 345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen MessageLoop message_loop(message_loop_type); 355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // A manual-reset event that is not yet signaled. 375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen WaitableEvent event(true, false); 385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 395abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick WaitableEventWatcher watcher; 405abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick EXPECT_TRUE(watcher.GetWatchedEvent() == NULL); 41e14391e94c850b8bd03680c23b38978db68687a8John Reck 425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen QuitDelegate delegate; 435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen watcher.StartWatching(&event, &delegate); 445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen EXPECT_EQ(&event, watcher.GetWatchedEvent()); 455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen event.Signal(); 475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 4868513a70bcd92384395513322f1b801e7bf9c729Steve Block MessageLoop::current()->Run(); 495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen EXPECT_TRUE(watcher.GetWatchedEvent() == NULL); 515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid RunTest_BasicCancel(MessageLoop::Type message_loop_type) { 545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen MessageLoop message_loop(message_loop_type); 555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // A manual-reset event that is not yet signaled. 572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block WaitableEvent event(true, false); 585abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 595abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick WaitableEventWatcher watcher; 605abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 615abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick QuitDelegate delegate; 625abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick watcher.StartWatching(&event, &delegate); 635abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch watcher.StopWatching(); 655abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick} 665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 675abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid RunTest_CancelAfterSet(MessageLoop::Type message_loop_type) { 685abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick MessageLoop message_loop(message_loop_type); 695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // A manual-reset event that is not yet signaled. 715ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen WaitableEvent event(true, false); 725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen WaitableEventWatcher watcher; 745ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 755ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen int counter = 1; 765ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen DecrementCountDelegate delegate(&counter); 775ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen watcher.StartWatching(&event, &delegate); 795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 805ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen event.Signal(); 815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 825ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // Let the background thread do its business 8368513a70bcd92384395513322f1b801e7bf9c729Steve Block base::PlatformThread::Sleep(30); 845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen watcher.StopWatching(); 865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 87f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MessageLoop::current()->RunAllPending(); 885ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 89f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Our delegate should not have fired. 905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen EXPECT_EQ(1, counter); 915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 92cad810f21b803229eb11403f9209855525a25d57Steve Block 935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid RunTest_OutlivesMessageLoop(MessageLoop::Type message_loop_type) { 945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // Simulate a MessageLoop that dies before an WaitableEventWatcher. This 955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // ordinarily doesn't happen when people use the Thread class, but it can 965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // happen when people use the Singleton pattern or atexit. 975abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick WaitableEvent event(true, false); 985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen { 99 WaitableEventWatcher watcher; 100 { 101 MessageLoop message_loop(message_loop_type); 102 103 QuitDelegate delegate; 104 watcher.StartWatching(&event, &delegate); 105 } 106 } 107} 108 109void RunTest_DeleteUnder(MessageLoop::Type message_loop_type) { 110 // Delete the WaitableEvent out from under the Watcher. This is explictly 111 // allowed by the interface. 112 113 MessageLoop message_loop(message_loop_type); 114 115 { 116 WaitableEventWatcher watcher; 117 118 WaitableEvent* event = new WaitableEvent(false, false); 119 QuitDelegate delegate; 120 watcher.StartWatching(event, &delegate); 121 delete event; 122 } 123} 124 125} // namespace 126 127//----------------------------------------------------------------------------- 128 129TEST(WaitableEventWatcherTest, BasicSignal) { 130 RunTest_BasicSignal(MessageLoop::TYPE_DEFAULT); 131 RunTest_BasicSignal(MessageLoop::TYPE_IO); 132 RunTest_BasicSignal(MessageLoop::TYPE_UI); 133} 134 135TEST(WaitableEventWatcherTest, BasicCancel) { 136 RunTest_BasicCancel(MessageLoop::TYPE_DEFAULT); 137 RunTest_BasicCancel(MessageLoop::TYPE_IO); 138 RunTest_BasicCancel(MessageLoop::TYPE_UI); 139} 140 141TEST(WaitableEventWatcherTest, CancelAfterSet) { 142 RunTest_CancelAfterSet(MessageLoop::TYPE_DEFAULT); 143 RunTest_CancelAfterSet(MessageLoop::TYPE_IO); 144 RunTest_CancelAfterSet(MessageLoop::TYPE_UI); 145} 146 147TEST(WaitableEventWatcherTest, OutlivesMessageLoop) { 148 RunTest_OutlivesMessageLoop(MessageLoop::TYPE_DEFAULT); 149 RunTest_OutlivesMessageLoop(MessageLoop::TYPE_IO); 150 RunTest_OutlivesMessageLoop(MessageLoop::TYPE_UI); 151} 152 153#if defined(OS_WIN) 154// Crashes sometimes on vista. http://crbug.com/62119 155#define MAYBE_DeleteUnder DISABLED_DeleteUnder 156#else 157#define MAYBE_DeleteUnder DeleteUnder 158#endif 159TEST(WaitableEventWatcherTest, MAYBE_DeleteUnder) { 160 RunTest_DeleteUnder(MessageLoop::TYPE_DEFAULT); 161 RunTest_DeleteUnder(MessageLoop::TYPE_IO); 162 RunTest_DeleteUnder(MessageLoop::TYPE_UI); 163} 164 165} // namespace base 166