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