blob: cbf8df2b7da396062514a09e167b8f7231c01c01 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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_