• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Based on
6 // https://cs.chromium.org/chromium/src/v8/src/base/platform/semaphore.cc
7 
8 #include "util/semaphore.h"
9 
10 #include "base/logging.h"
11 
12 #if defined(OS_WIN)
13 #include <windows.h>
14 #endif
15 
16 #if defined(OS_MACOSX)
17 
Semaphore(int count)18 Semaphore::Semaphore(int count) {
19   native_handle_ = dispatch_semaphore_create(count);
20   DCHECK(native_handle_);
21 }
22 
~Semaphore()23 Semaphore::~Semaphore() {
24   dispatch_release(native_handle_);
25 }
26 
Signal()27 void Semaphore::Signal() {
28   dispatch_semaphore_signal(native_handle_);
29 }
30 
Wait()31 void Semaphore::Wait() {
32   dispatch_semaphore_wait(native_handle_, DISPATCH_TIME_FOREVER);
33 }
34 
35 #elif defined(OS_POSIX)
36 
Semaphore(int count)37 Semaphore::Semaphore(int count) {
38   DCHECK_GE(count, 0);
39   int result = sem_init(&native_handle_, 0, count);
40   DCHECK_EQ(0, result);
41 }
42 
~Semaphore()43 Semaphore::~Semaphore() {
44   int result = sem_destroy(&native_handle_);
45   DCHECK_EQ(0, result);
46 }
47 
Signal()48 void Semaphore::Signal() {
49   int result = sem_post(&native_handle_);
50   // This check may fail with <libc-2.21, which we use on the try bots, if the
51   // semaphore is destroyed while sem_post is still executed. A work around is
52   // to extend the lifetime of the semaphore.
53   CHECK_EQ(0, result);
54 }
55 
Wait()56 void Semaphore::Wait() {
57   while (true) {
58     int result = sem_wait(&native_handle_);
59     if (result == 0)
60       return;  // Semaphore was signalled.
61     // Signal caused spurious wakeup.
62     DCHECK_EQ(-1, result);
63     DCHECK_EQ(EINTR, errno);
64   }
65 }
66 
67 #elif defined(OS_WIN)
68 
Semaphore(int count)69 Semaphore::Semaphore(int count) {
70   DCHECK_GE(count, 0);
71   native_handle_ = ::CreateSemaphoreA(nullptr, count, 0x7FFFFFFF, nullptr);
72   DCHECK(native_handle_);
73 }
74 
~Semaphore()75 Semaphore::~Semaphore() {
76   BOOL result = CloseHandle(native_handle_);
77   DCHECK(result);
78 }
79 
Signal()80 void Semaphore::Signal() {
81   LONG dummy;
82   BOOL result = ReleaseSemaphore(native_handle_, 1, &dummy);
83   DCHECK(result);
84 }
85 
Wait()86 void Semaphore::Wait() {
87   DWORD result = WaitForSingleObject(native_handle_, INFINITE);
88   DCHECK(result == WAIT_OBJECT_0);
89 }
90 
91 #endif
92