Home | History | Annotate | Download | only in synchronization
      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