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 "base/compiler_specific.h" 8 #include "base/threading/platform_thread.h" 9 #include "base/time/time.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 12 namespace base { 13 14 TEST(WaitableEventTest, ManualBasics) { 15 WaitableEvent event(true, false); 16 17 EXPECT_FALSE(event.IsSignaled()); 18 19 event.Signal(); 20 EXPECT_TRUE(event.IsSignaled()); 21 EXPECT_TRUE(event.IsSignaled()); 22 23 event.Reset(); 24 EXPECT_FALSE(event.IsSignaled()); 25 EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10))); 26 27 event.Signal(); 28 event.Wait(); 29 EXPECT_TRUE(event.TimedWait(TimeDelta::FromMilliseconds(10))); 30 } 31 32 TEST(WaitableEventTest, AutoBasics) { 33 WaitableEvent event(false, false); 34 35 EXPECT_FALSE(event.IsSignaled()); 36 37 event.Signal(); 38 EXPECT_TRUE(event.IsSignaled()); 39 EXPECT_FALSE(event.IsSignaled()); 40 41 event.Reset(); 42 EXPECT_FALSE(event.IsSignaled()); 43 EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10))); 44 45 event.Signal(); 46 event.Wait(); 47 EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10))); 48 49 event.Signal(); 50 EXPECT_TRUE(event.TimedWait(TimeDelta::FromMilliseconds(10))); 51 } 52 53 TEST(WaitableEventTest, WaitManyShortcut) { 54 WaitableEvent* ev[5]; 55 for (unsigned i = 0; i < 5; ++i) 56 ev[i] = new WaitableEvent(false, false); 57 58 ev[3]->Signal(); 59 EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 3u); 60 61 ev[3]->Signal(); 62 EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 3u); 63 64 ev[4]->Signal(); 65 EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 4u); 66 67 ev[0]->Signal(); 68 EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 0u); 69 70 for (unsigned i = 0; i < 5; ++i) 71 delete ev[i]; 72 } 73 74 class WaitableEventSignaler : public PlatformThread::Delegate { 75 public: 76 WaitableEventSignaler(double seconds, WaitableEvent* ev) 77 : seconds_(seconds), 78 ev_(ev) { 79 } 80 81 virtual void ThreadMain() OVERRIDE { 82 PlatformThread::Sleep(TimeDelta::FromSecondsD(seconds_)); 83 ev_->Signal(); 84 } 85 86 private: 87 const double seconds_; 88 WaitableEvent *const ev_; 89 }; 90 91 TEST(WaitableEventTest, WaitAndDelete) { 92 // This test tests that if a WaitableEvent can be safely deleted 93 // when |Wait| is done without additional synchrnization. 94 // If this test crashes, it is a bug. 95 96 WaitableEvent* ev = new WaitableEvent(false, false); 97 98 WaitableEventSignaler signaler(0.01, ev); 99 PlatformThreadHandle thread; 100 PlatformThread::Create(0, &signaler, &thread); 101 102 ev->Wait(); 103 delete ev; 104 105 PlatformThread::Join(thread); 106 } 107 108 TEST(WaitableEventTest, WaitMany) { 109 // This test tests that if a WaitableEvent can be safely deleted 110 // when |WaitMany| is done without additional synchrnization. 111 // If this test crashes, it is a bug. 112 113 WaitableEvent* ev[5]; 114 for (unsigned i = 0; i < 5; ++i) 115 ev[i] = new WaitableEvent(false, false); 116 117 WaitableEventSignaler signaler(0.01, ev[2]); 118 PlatformThreadHandle thread; 119 PlatformThread::Create(0, &signaler, &thread); 120 121 size_t index = WaitableEvent::WaitMany(ev, 5); 122 123 for (unsigned i = 0; i < 5; ++i) 124 delete ev[i]; 125 126 PlatformThread::Join(thread); 127 EXPECT_EQ(2u, index); 128 } 129 130 } // namespace base 131