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 15namespace base { 16 17TEST(WaitableEventTest, ManualBasics) { 18 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, 19 WaitableEvent::InitialState::NOT_SIGNALED); 20 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) { 37 WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC, 38 WaitableEvent::InitialState::NOT_SIGNALED); 39 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]; 60 for (unsigned i = 0; i < 5; ++i) { 61 ev[i] = new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC, 62 WaitableEvent::InitialState::NOT_SIGNALED); 63 } 64 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) { 101 WaitableEvent* ev = 102 new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC, 103 WaitableEvent::InitialState::NOT_SIGNALED); 104 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]; 119 for (unsigned i = 0; i < 5; ++i) { 120 ev[i] = new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC, 121 WaitableEvent::InitialState::NOT_SIGNALED); 122 } 123 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) 139#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) { 146 WaitableEvent* ev = 147 new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC, 148 WaitableEvent::InitialState::NOT_SIGNALED); 149 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 156 ev->TimedWait(TimeDelta::Max()); 157 EXPECT_GE(TimeTicks::Now() - start, thread_delay); 158 delete ev; 159 160 PlatformThread::Join(thread); 161} 162 163} // namespace base 164