blob: ac5c9f125584da09b4a829cf24f8a250e8f81ab8 [file] [log] [blame]
Daniel Eratb8cf9492015-07-06 13:18:13 -06001// Copyright (c) 2012 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 "base/synchronization/waitable_event.h"
6
Alex Vakulenko0d205d72016-01-15 13:02:14 -08007#include <stddef.h>
8
Daniel Eratb8cf9492015-07-06 13:18:13 -06009#include "base/compiler_specific.h"
10#include "base/threading/platform_thread.h"
11#include "base/time/time.h"
Alex Vakulenko0d205d72016-01-15 13:02:14 -080012#include "build/build_config.h"
Daniel Eratb8cf9492015-07-06 13:18:13 -060013#include "testing/gtest/include/gtest/gtest.h"
14
15namespace base {
16
17TEST(WaitableEventTest, ManualBasics) {
Luis Hector Chavez0c4f26a2016-07-15 16:23:21 -070018 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
19 WaitableEvent::InitialState::NOT_SIGNALED);
Daniel Eratb8cf9492015-07-06 13:18:13 -060020
21 EXPECT_FALSE(event.IsSignaled());
22
23 event.Signal();
24 EXPECT_TRUE(event.IsSignaled());
25 EXPECT_TRUE(event.IsSignaled());
26
27 event.Reset();
28 EXPECT_FALSE(event.IsSignaled());
29 EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10)));
30
31 event.Signal();
32 event.Wait();
33 EXPECT_TRUE(event.TimedWait(TimeDelta::FromMilliseconds(10)));
34}
35
36TEST(WaitableEventTest, AutoBasics) {
Luis Hector Chavez0c4f26a2016-07-15 16:23:21 -070037 WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC,
38 WaitableEvent::InitialState::NOT_SIGNALED);
Daniel Eratb8cf9492015-07-06 13:18:13 -060039
40 EXPECT_FALSE(event.IsSignaled());
41
42 event.Signal();
43 EXPECT_TRUE(event.IsSignaled());
44 EXPECT_FALSE(event.IsSignaled());
45
46 event.Reset();
47 EXPECT_FALSE(event.IsSignaled());
48 EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10)));
49
50 event.Signal();
51 event.Wait();
52 EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10)));
53
54 event.Signal();
55 EXPECT_TRUE(event.TimedWait(TimeDelta::FromMilliseconds(10)));
56}
57
58TEST(WaitableEventTest, WaitManyShortcut) {
59 WaitableEvent* ev[5];
Luis Hector Chavez0c4f26a2016-07-15 16:23:21 -070060 for (unsigned i = 0; i < 5; ++i) {
61 ev[i] = new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC,
62 WaitableEvent::InitialState::NOT_SIGNALED);
63 }
Daniel Eratb8cf9492015-07-06 13:18:13 -060064
65 ev[3]->Signal();
66 EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 3u);
67
68 ev[3]->Signal();
69 EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 3u);
70
71 ev[4]->Signal();
72 EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 4u);
73
74 ev[0]->Signal();
75 EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 0u);
76
77 for (unsigned i = 0; i < 5; ++i)
78 delete ev[i];
79}
80
81class WaitableEventSignaler : public PlatformThread::Delegate {
82 public:
83 WaitableEventSignaler(TimeDelta delay, WaitableEvent* event)
84 : delay_(delay),
85 event_(event) {
86 }
87
88 void ThreadMain() override {
89 PlatformThread::Sleep(delay_);
90 event_->Signal();
91 }
92
93 private:
94 const TimeDelta delay_;
95 WaitableEvent* event_;
96};
97
98// Tests that a WaitableEvent can be safely deleted when |Wait| is done without
99// additional synchronization.
100TEST(WaitableEventTest, WaitAndDelete) {
Luis Hector Chavez0c4f26a2016-07-15 16:23:21 -0700101 WaitableEvent* ev =
102 new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC,
103 WaitableEvent::InitialState::NOT_SIGNALED);
Daniel Eratb8cf9492015-07-06 13:18:13 -0600104
105 WaitableEventSignaler signaler(TimeDelta::FromMilliseconds(10), ev);
106 PlatformThreadHandle thread;
107 PlatformThread::Create(0, &signaler, &thread);
108
109 ev->Wait();
110 delete ev;
111
112 PlatformThread::Join(thread);
113}
114
115// Tests that a WaitableEvent can be safely deleted when |WaitMany| is done
116// without additional synchronization.
117TEST(WaitableEventTest, WaitMany) {
118 WaitableEvent* ev[5];
Luis Hector Chavez0c4f26a2016-07-15 16:23:21 -0700119 for (unsigned i = 0; i < 5; ++i) {
120 ev[i] = new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC,
121 WaitableEvent::InitialState::NOT_SIGNALED);
122 }
Daniel Eratb8cf9492015-07-06 13:18:13 -0600123
124 WaitableEventSignaler signaler(TimeDelta::FromMilliseconds(10), ev[2]);
125 PlatformThreadHandle thread;
126 PlatformThread::Create(0, &signaler, &thread);
127
128 size_t index = WaitableEvent::WaitMany(ev, 5);
129
130 for (unsigned i = 0; i < 5; ++i)
131 delete ev[i];
132
133 PlatformThread::Join(thread);
134 EXPECT_EQ(2u, index);
135}
136
137// Tests that using TimeDelta::Max() on TimedWait() is not the same as passing
138// a timeout of 0. (crbug.com/465948)
Luis Hector Chaveze5b2c6f2017-07-26 17:33:47 +0000139#if defined(OS_POSIX)
140// crbug.com/465948 not fixed yet.
141#define MAYBE_TimedWait DISABLED_TimedWait
142#else
143#define MAYBE_TimedWait TimedWait
144#endif
145TEST(WaitableEventTest, MAYBE_TimedWait) {
Luis Hector Chavez0c4f26a2016-07-15 16:23:21 -0700146 WaitableEvent* ev =
147 new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC,
148 WaitableEvent::InitialState::NOT_SIGNALED);
Daniel Eratb8cf9492015-07-06 13:18:13 -0600149
150 TimeDelta thread_delay = TimeDelta::FromMilliseconds(10);
151 WaitableEventSignaler signaler(thread_delay, ev);
152 PlatformThreadHandle thread;
153 TimeTicks start = TimeTicks::Now();
154 PlatformThread::Create(0, &signaler, &thread);
155
Luis Hector Chaveze5b2c6f2017-07-26 17:33:47 +0000156 ev->TimedWait(TimeDelta::Max());
Daniel Eratb8cf9492015-07-06 13:18:13 -0600157 EXPECT_GE(TimeTicks::Now() - start, thread_delay);
158 delete ev;
159
160 PlatformThread::Join(thread);
161}
162
Daniel Eratb8cf9492015-07-06 13:18:13 -0600163} // namespace base