• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
7 #include <stddef.h>
8 
9 #include "base/compiler_specific.h"
10 #include "base/threading/platform_thread.h"
11 #include "base/time/time.h"
12 #include "build/build_config.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace base {
16 
TEST(WaitableEventTest,ManualBasics)17 TEST(WaitableEventTest, ManualBasics) {
18   WaitableEvent event(true, false);
19 
20   EXPECT_FALSE(event.IsSignaled());
21 
22   event.Signal();
23   EXPECT_TRUE(event.IsSignaled());
24   EXPECT_TRUE(event.IsSignaled());
25 
26   event.Reset();
27   EXPECT_FALSE(event.IsSignaled());
28   EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10)));
29 
30   event.Signal();
31   event.Wait();
32   EXPECT_TRUE(event.TimedWait(TimeDelta::FromMilliseconds(10)));
33 }
34 
TEST(WaitableEventTest,AutoBasics)35 TEST(WaitableEventTest, AutoBasics) {
36   WaitableEvent event(false, false);
37 
38   EXPECT_FALSE(event.IsSignaled());
39 
40   event.Signal();
41   EXPECT_TRUE(event.IsSignaled());
42   EXPECT_FALSE(event.IsSignaled());
43 
44   event.Reset();
45   EXPECT_FALSE(event.IsSignaled());
46   EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10)));
47 
48   event.Signal();
49   event.Wait();
50   EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10)));
51 
52   event.Signal();
53   EXPECT_TRUE(event.TimedWait(TimeDelta::FromMilliseconds(10)));
54 }
55 
TEST(WaitableEventTest,WaitManyShortcut)56 TEST(WaitableEventTest, WaitManyShortcut) {
57   WaitableEvent* ev[5];
58   for (unsigned i = 0; i < 5; ++i)
59     ev[i] = new WaitableEvent(false, false);
60 
61   ev[3]->Signal();
62   EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 3u);
63 
64   ev[3]->Signal();
65   EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 3u);
66 
67   ev[4]->Signal();
68   EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 4u);
69 
70   ev[0]->Signal();
71   EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 0u);
72 
73   for (unsigned i = 0; i < 5; ++i)
74     delete ev[i];
75 }
76 
77 class WaitableEventSignaler : public PlatformThread::Delegate {
78  public:
WaitableEventSignaler(TimeDelta delay,WaitableEvent * event)79   WaitableEventSignaler(TimeDelta delay, WaitableEvent* event)
80       : delay_(delay),
81         event_(event) {
82   }
83 
ThreadMain()84   void ThreadMain() override {
85     PlatformThread::Sleep(delay_);
86     event_->Signal();
87   }
88 
89  private:
90   const TimeDelta delay_;
91   WaitableEvent* event_;
92 };
93 
94 // Tests that a WaitableEvent can be safely deleted when |Wait| is done without
95 // additional synchronization.
TEST(WaitableEventTest,WaitAndDelete)96 TEST(WaitableEventTest, WaitAndDelete) {
97   WaitableEvent* ev = new WaitableEvent(false, false);
98 
99   WaitableEventSignaler signaler(TimeDelta::FromMilliseconds(10), ev);
100   PlatformThreadHandle thread;
101   PlatformThread::Create(0, &signaler, &thread);
102 
103   ev->Wait();
104   delete ev;
105 
106   PlatformThread::Join(thread);
107 }
108 
109 // Tests that a WaitableEvent can be safely deleted when |WaitMany| is done
110 // without additional synchronization.
TEST(WaitableEventTest,WaitMany)111 TEST(WaitableEventTest, WaitMany) {
112   WaitableEvent* ev[5];
113   for (unsigned i = 0; i < 5; ++i)
114     ev[i] = new WaitableEvent(false, false);
115 
116   WaitableEventSignaler signaler(TimeDelta::FromMilliseconds(10), ev[2]);
117   PlatformThreadHandle thread;
118   PlatformThread::Create(0, &signaler, &thread);
119 
120   size_t index = WaitableEvent::WaitMany(ev, 5);
121 
122   for (unsigned i = 0; i < 5; ++i)
123     delete ev[i];
124 
125   PlatformThread::Join(thread);
126   EXPECT_EQ(2u, index);
127 }
128 
129 // Tests that using TimeDelta::Max() on TimedWait() is not the same as passing
130 // a timeout of 0. (crbug.com/465948)
131 #if defined(OS_POSIX)
132 // crbug.com/465948 not fixed yet.
133 #define MAYBE_TimedWait DISABLED_TimedWait
134 #else
135 #define MAYBE_TimedWait TimedWait
136 #endif
TEST(WaitableEventTest,MAYBE_TimedWait)137 TEST(WaitableEventTest, MAYBE_TimedWait) {
138   WaitableEvent* ev = new WaitableEvent(false, false);
139 
140   TimeDelta thread_delay = TimeDelta::FromMilliseconds(10);
141   WaitableEventSignaler signaler(thread_delay, ev);
142   PlatformThreadHandle thread;
143   TimeTicks start = TimeTicks::Now();
144   PlatformThread::Create(0, &signaler, &thread);
145 
146   ev->TimedWait(TimeDelta::Max());
147   EXPECT_GE(TimeTicks::Now() - start, thread_delay);
148   delete ev;
149 
150   PlatformThread::Join(thread);
151 }
152 
153 }  // namespace base
154