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/base-export.h" 9#include "src/base/lazy-instance.h" 10#if V8_OS_WIN 11#include "src/base/win32-headers.h" 12#endif 13 14#if V8_OS_MACOSX 15#include <mach/semaphore.h> // NOLINT 16#elif V8_OS_POSIX 17#include <semaphore.h> // NOLINT 18#endif 19 20namespace v8 { 21namespace base { 22 23// Forward declarations. 24class TimeDelta; 25 26// ---------------------------------------------------------------------------- 27// Semaphore 28// 29// A semaphore object is a synchronization object that maintains a count. The 30// count is decremented each time a thread completes a wait for the semaphore 31// object and incremented each time a thread signals the semaphore. When the 32// count reaches zero, threads waiting for the semaphore blocks until the 33// count becomes non-zero. 34 35class V8_BASE_EXPORT Semaphore final { 36 public: 37 explicit Semaphore(int count); 38 ~Semaphore(); 39 40 // Increments the semaphore counter. 41 void Signal(); 42 43 // Decrements the semaphore counter if it is positive, or blocks until it 44 // becomes positive and then decrements the counter. 45 void Wait(); 46 47 // Like Wait() but returns after rel_time time has passed. If the timeout 48 // happens the return value is false and the counter is unchanged. Otherwise 49 // the semaphore counter is decremented and 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 base 100} // namespace v8 101 102#endif // V8_BASE_PLATFORM_SEMAPHORE_H_ 103