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/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 
     20 namespace v8 {
     21 namespace base {
     22 
     23 // Forward declarations.
     24 class 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 
     35 class 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 
     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 base
    100 }  // namespace v8
    101 
    102 #endif  // V8_BASE_PLATFORM_SEMAPHORE_H_
    103