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