1// Copyright 2013 the V8 project 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#ifndef V8_BASE_PLATFORM_SEMAPHORE_H_ 6#define V8_BASE_PLATFORM_SEMAPHORE_H_ 7 8#include "src/base/lazy-instance.h" 9#if V8_OS_WIN 10#include "src/base/win32-headers.h" 11#endif 12 13#if V8_OS_MACOSX 14#include <mach/semaphore.h> // NOLINT 15#elif V8_OS_POSIX 16#include <semaphore.h> // NOLINT 17#endif 18 19namespace v8 { 20namespace base { 21 22// Forward declarations. 23class TimeDelta; 24 25// ---------------------------------------------------------------------------- 26// Semaphore 27// 28// A semaphore object is a synchronization object that maintains a count. The 29// count is decremented each time a thread completes a wait for the semaphore 30// object and incremented each time a thread signals the semaphore. When the 31// count reaches zero, threads waiting for the semaphore blocks until the 32// count becomes non-zero. 33 34class Semaphore FINAL { 35 public: 36 explicit Semaphore(int count); 37 ~Semaphore(); 38 39 // Increments the semaphore counter. 40 void Signal(); 41 42 // Suspends the calling thread until the semaphore counter is non zero 43 // and then decrements the semaphore counter. 44 void Wait(); 45 46 // Suspends the calling thread until the counter is non zero or the timeout 47 // time has passed. If timeout happens the return value is false and the 48 // counter is unchanged. Otherwise the semaphore counter is decremented and 49 // true is returned. 50 bool WaitFor(const TimeDelta& rel_time) WARN_UNUSED_RESULT; 51 52#if V8_OS_MACOSX 53 typedef semaphore_t NativeHandle; 54#elif V8_OS_POSIX 55 typedef sem_t NativeHandle; 56#elif V8_OS_WIN 57 typedef HANDLE NativeHandle; 58#endif 59 60 NativeHandle& native_handle() { 61 return native_handle_; 62 } 63 const NativeHandle& native_handle() const { 64 return native_handle_; 65 } 66 67 private: 68 NativeHandle native_handle_; 69 70 DISALLOW_COPY_AND_ASSIGN(Semaphore); 71}; 72 73 74// POD Semaphore initialized lazily (i.e. the first time Pointer() is called). 75// Usage: 76// // The following semaphore starts at 0. 77// static LazySemaphore<0>::type my_semaphore = LAZY_SEMAPHORE_INITIALIZER; 78// 79// void my_function() { 80// // Do something with my_semaphore.Pointer(). 81// } 82// 83 84template <int N> 85struct CreateSemaphoreTrait { 86 static Semaphore* Create() { 87 return new Semaphore(N); 88 } 89}; 90 91template <int N> 92struct LazySemaphore { 93 typedef typename LazyDynamicInstance<Semaphore, CreateSemaphoreTrait<N>, 94 ThreadSafeInitOnceTrait>::type type; 95}; 96 97#define LAZY_SEMAPHORE_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER 98 99} } // namespace v8::base 100 101#endif // V8_BASE_PLATFORM_SEMAPHORE_H_ 102