blob: 58444b3c4ef2b861cb66e5bc71e4f340289271b0 [file] [log] [blame]
[email protected]44106182012-04-06 03:53:021// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]1c4947f2009-01-15 22:25:112// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]f7b98b32013-02-05 08:14:155#include "base/synchronization/waitable_event_watcher.h"
6
[email protected]329be052013-02-04 18:14:287#include "base/bind.h"
8#include "base/callback.h"
avi9b6f42932015-12-26 22:15:149#include "base/macros.h"
[email protected]495cad92013-07-18 08:12:4010#include "base/message_loop/message_loop.h"
[email protected]f7b98b32013-02-05 08:14:1511#include "base/run_loop.h"
[email protected]44f9c952011-01-02 06:05:3912#include "base/synchronization/waitable_event.h"
[email protected]ce072a72010-12-31 20:02:1613#include "base/threading/platform_thread.h"
avi9b6f42932015-12-26 22:15:1414#include "build/build_config.h"
[email protected]1c4947f2009-01-15 22:25:1115#include "testing/gtest/include/gtest/gtest.h"
16
[email protected]44f9c952011-01-02 06:05:3917namespace base {
[email protected]1c4947f2009-01-15 22:25:1118
19namespace {
20
[email protected]840246b2012-07-18 08:06:5021// The message loops on which each waitable event timer should be tested.
22const MessageLoop::Type testing_message_loops[] = {
23 MessageLoop::TYPE_DEFAULT,
24 MessageLoop::TYPE_IO,
25#if !defined(OS_IOS) // iOS does not allow direct running of the UI loop.
26 MessageLoop::TYPE_UI,
27#endif
28};
29
30const int kNumTestingMessageLoops = arraysize(testing_message_loops);
31
[email protected]329be052013-02-04 18:14:2832void QuitWhenSignaled(WaitableEvent* event) {
33 MessageLoop::current()->QuitWhenIdle();
34}
[email protected]1eaa54792013-01-31 23:14:2735
[email protected]329be052013-02-04 18:14:2836class DecrementCountContainer {
[email protected]1eaa54792013-01-31 23:14:2737 public:
[email protected]329be052013-02-04 18:14:2838 explicit DecrementCountContainer(int* counter) : counter_(counter) {
[email protected]1eaa54792013-01-31 23:14:2739 }
[email protected]329be052013-02-04 18:14:2840 void OnWaitableEventSignaled(WaitableEvent* object) {
[email protected]1c4947f2009-01-15 22:25:1141 --(*counter_);
42 }
43 private:
44 int* counter_;
45};
46
[email protected]1c4947f2009-01-15 22:25:1147void RunTest_BasicSignal(MessageLoop::Type message_loop_type) {
48 MessageLoop message_loop(message_loop_type);
49
50 // A manual-reset event that is not yet signaled.
51 WaitableEvent event(true, false);
52
53 WaitableEventWatcher watcher;
[email protected]9b6fee12009-09-29 18:13:0754 EXPECT_TRUE(watcher.GetWatchedEvent() == NULL);
[email protected]1c4947f2009-01-15 22:25:1155
[email protected]329be052013-02-04 18:14:2856 watcher.StartWatching(&event, Bind(&QuitWhenSignaled));
[email protected]5b7a6ce2009-01-15 22:31:1757 EXPECT_EQ(&event, watcher.GetWatchedEvent());
[email protected]1c4947f2009-01-15 22:25:1158
59 event.Signal();
60
61 MessageLoop::current()->Run();
62
[email protected]9b6fee12009-09-29 18:13:0763 EXPECT_TRUE(watcher.GetWatchedEvent() == NULL);
[email protected]1c4947f2009-01-15 22:25:1164}
65
66void RunTest_BasicCancel(MessageLoop::Type message_loop_type) {
67 MessageLoop message_loop(message_loop_type);
68
69 // A manual-reset event that is not yet signaled.
70 WaitableEvent event(true, false);
71
72 WaitableEventWatcher watcher;
73
[email protected]329be052013-02-04 18:14:2874 watcher.StartWatching(&event, Bind(&QuitWhenSignaled));
[email protected]1c4947f2009-01-15 22:25:1175
76 watcher.StopWatching();
77}
78
79void RunTest_CancelAfterSet(MessageLoop::Type message_loop_type) {
80 MessageLoop message_loop(message_loop_type);
81
82 // A manual-reset event that is not yet signaled.
83 WaitableEvent event(true, false);
84
85 WaitableEventWatcher watcher;
86
87 int counter = 1;
[email protected]329be052013-02-04 18:14:2888 DecrementCountContainer delegate(&counter);
89 WaitableEventWatcher::EventCallback callback =
90 Bind(&DecrementCountContainer::OnWaitableEventSignaled,
91 Unretained(&delegate));
92 watcher.StartWatching(&event, callback);
[email protected]1c4947f2009-01-15 22:25:1193
94 event.Signal();
95
96 // Let the background thread do its business
[email protected]a1b75b942011-12-31 22:53:5197 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30));
[email protected]1c4947f2009-01-15 22:25:1198
99 watcher.StopWatching();
100
[email protected]f7b98b32013-02-05 08:14:15101 RunLoop().RunUntilIdle();
[email protected]1c4947f2009-01-15 22:25:11102
103 // Our delegate should not have fired.
104 EXPECT_EQ(1, counter);
105}
106
107void RunTest_OutlivesMessageLoop(MessageLoop::Type message_loop_type) {
108 // Simulate a MessageLoop that dies before an WaitableEventWatcher. This
109 // ordinarily doesn't happen when people use the Thread class, but it can
110 // happen when people use the Singleton pattern or atexit.
111 WaitableEvent event(true, false);
112 {
113 WaitableEventWatcher watcher;
114 {
115 MessageLoop message_loop(message_loop_type);
116
[email protected]329be052013-02-04 18:14:28117 watcher.StartWatching(&event, Bind(&QuitWhenSignaled));
[email protected]1c4947f2009-01-15 22:25:11118 }
119 }
120}
121
[email protected]c891ab92009-03-26 18:28:19122void RunTest_DeleteUnder(MessageLoop::Type message_loop_type) {
123 // Delete the WaitableEvent out from under the Watcher. This is explictly
124 // allowed by the interface.
125
126 MessageLoop message_loop(message_loop_type);
127
128 {
129 WaitableEventWatcher watcher;
130
131 WaitableEvent* event = new WaitableEvent(false, false);
[email protected]329be052013-02-04 18:14:28132
133 watcher.StartWatching(event, Bind(&QuitWhenSignaled));
[email protected]c891ab92009-03-26 18:28:19134 delete event;
135 }
136}
137
[email protected]b57d33c52009-01-15 22:58:53138} // namespace
139
[email protected]1c4947f2009-01-15 22:25:11140//-----------------------------------------------------------------------------
141
[email protected]9480d2ab2009-01-15 22:52:38142TEST(WaitableEventWatcherTest, BasicSignal) {
[email protected]840246b2012-07-18 08:06:50143 for (int i = 0; i < kNumTestingMessageLoops; i++) {
144 RunTest_BasicSignal(testing_message_loops[i]);
145 }
[email protected]1c4947f2009-01-15 22:25:11146}
147
[email protected]9480d2ab2009-01-15 22:52:38148TEST(WaitableEventWatcherTest, BasicCancel) {
[email protected]840246b2012-07-18 08:06:50149 for (int i = 0; i < kNumTestingMessageLoops; i++) {
150 RunTest_BasicCancel(testing_message_loops[i]);
151 }
[email protected]1c4947f2009-01-15 22:25:11152}
153
[email protected]9480d2ab2009-01-15 22:52:38154TEST(WaitableEventWatcherTest, CancelAfterSet) {
[email protected]840246b2012-07-18 08:06:50155 for (int i = 0; i < kNumTestingMessageLoops; i++) {
156 RunTest_CancelAfterSet(testing_message_loops[i]);
157 }
[email protected]1c4947f2009-01-15 22:25:11158}
159
[email protected]9480d2ab2009-01-15 22:52:38160TEST(WaitableEventWatcherTest, OutlivesMessageLoop) {
[email protected]840246b2012-07-18 08:06:50161 for (int i = 0; i < kNumTestingMessageLoops; i++) {
162 RunTest_OutlivesMessageLoop(testing_message_loops[i]);
163 }
[email protected]1c4947f2009-01-15 22:25:11164}
[email protected]c891ab92009-03-26 18:28:19165
[email protected]a18194a2010-11-05 22:03:31166#if defined(OS_WIN)
167// Crashes sometimes on vista. http://crbug.com/62119
168#define MAYBE_DeleteUnder DISABLED_DeleteUnder
169#else
170#define MAYBE_DeleteUnder DeleteUnder
171#endif
172TEST(WaitableEventWatcherTest, MAYBE_DeleteUnder) {
[email protected]840246b2012-07-18 08:06:50173 for (int i = 0; i < kNumTestingMessageLoops; i++) {
174 RunTest_DeleteUnder(testing_message_loops[i]);
175 }
[email protected]c891ab92009-03-26 18:28:19176}
[email protected]44f9c952011-01-02 06:05:39177
178} // namespace base