15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WaitableEventTest, ManualBasics) { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent event(true, false); 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(event.IsSignaled()); 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Signal(); 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(event.IsSignaled()); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(event.IsSignaled()); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Reset(); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(event.IsSignaled()); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10))); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Signal(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Wait(); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(event.TimedWait(TimeDelta::FromMilliseconds(10))); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WaitableEventTest, AutoBasics) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent event(false, false); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(event.IsSignaled()); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Signal(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(event.IsSignaled()); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(event.IsSignaled()); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Reset(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(event.IsSignaled()); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10))); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Signal(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Wait(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(event.TimedWait(TimeDelta::FromMilliseconds(10))); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Signal(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(event.TimedWait(TimeDelta::FromMilliseconds(10))); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WaitableEventTest, WaitManyShortcut) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* ev[5]; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < 5; ++i) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev[i] = new WaitableEvent(false, false); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev[3]->Signal(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 3u); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev[3]->Signal(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 3u); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev[4]->Signal(); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 4u); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev[0]->Signal(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(WaitableEvent::WaitMany(ev, 5), 0u); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < 5; ++i) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete ev[i]; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WaitableEventSignaler : public PlatformThread::Delegate { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEventSignaler(double seconds, WaitableEvent* ev) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : seconds_(seconds), 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev_(ev) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ThreadMain() OVERRIDE { 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PlatformThread::Sleep(TimeDelta::FromSecondsD(seconds_)); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev_->Signal(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double seconds_; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent *const ev_; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST(WaitableEventTest, WaitAndDelete) { 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // This test tests that if a WaitableEvent can be safely deleted 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // when |Wait| is done without additional synchrnization. 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If this test crashes, it is a bug. 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WaitableEvent* ev = new WaitableEvent(false, false); 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WaitableEventSignaler signaler(0.01, ev); 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PlatformThreadHandle thread; 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PlatformThread::Create(0, &signaler, &thread); 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ev->Wait(); 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delete ev; 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PlatformThread::Join(thread); 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(WaitableEventTest, WaitMany) { 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // This test tests that if a WaitableEvent can be safely deleted 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // when |WaitMany| is done without additional synchrnization. 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If this test crashes, it is a bug. 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* ev[5]; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < 5; ++i) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev[i] = new WaitableEvent(false, false); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WaitableEventSignaler signaler(0.01, ev[2]); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformThreadHandle thread; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformThread::Create(0, &signaler, &thread); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t index = WaitableEvent::WaitMany(ev, 5); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < 5; ++i) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete ev[i]; 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PlatformThread::Join(thread); 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(2u, index); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 131