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 19 namespace v8 { 20 namespace base { 21 22 // Forward declarations. 23 class 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 34 class 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 84 template <int N> 85 struct CreateSemaphoreTrait { 86 static Semaphore* Create() { 87 return new Semaphore(N); 88 } 89 }; 90 91 template <int N> 92 struct 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