/src/hermes/lib/Support/SemaphorePosix.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) Meta Platforms, Inc. and affiliates. |
3 | | * |
4 | | * This source code is licensed under the MIT license found in the |
5 | | * LICENSE file in the root directory of this source tree. |
6 | | */ |
7 | | |
8 | | #ifndef _WINDOWS |
9 | | |
10 | | #include "hermes/Support/Semaphore.h" |
11 | | |
12 | | #include "hermes/Support/OSCompat.h" |
13 | | |
14 | | #include "llvh/ADT/SmallVector.h" |
15 | | #include "llvh/Support/raw_ostream.h" |
16 | | |
17 | | #include <cstdio> |
18 | | #include <string> |
19 | | |
20 | | namespace hermes { |
21 | | |
22 | 0 | sem_t *Semaphore::getSemaphorePtr() { |
23 | | #ifdef __APPLE__ |
24 | | return semPtr_; |
25 | | #else |
26 | 0 | return &sem_; |
27 | 0 | #endif |
28 | 0 | } |
29 | | |
30 | 0 | bool Semaphore::open(const char *semaphorePrefix) { |
31 | | #ifdef __APPLE__ |
32 | | // Generate a unique name for the semaphore by postfixing semaphorePrefix with |
33 | | // the thread ID. This ensures that no other semaphore will be created with |
34 | | // the same name, avoiding unintentional sharing. |
35 | | llvh::SmallVector<char, 64> semaphoreName; |
36 | | llvh::raw_svector_ostream OS(semaphoreName); |
37 | | |
38 | | // oscompat::thread_id returns the OS level thread ID, and is thus system |
39 | | // unique. |
40 | | OS << semaphorePrefix << oscompat::thread_id(); |
41 | | |
42 | | // Create a named semaphore with read/write. Use O_EXCL as an extra protection |
43 | | // layer -- sem_open will fail if semaphoreName is not unique. |
44 | | semPtr_ = sem_open( |
45 | | semaphoreName.data(), O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, /*value*/ 0); |
46 | | if (semPtr_ == SEM_FAILED) { |
47 | | perror("sem_open"); |
48 | | return false; |
49 | | } |
50 | | assert(semPtr_ != nullptr && "sem_open should have succeeded"); |
51 | | |
52 | | // Now unlink the semaphore from its temporary name. This ensures that no |
53 | | // other Semaphore will share the underlying OS object. |
54 | | if (sem_unlink(semaphoreName.data()) != 0) { |
55 | | perror("sem_unlink"); |
56 | | return false; |
57 | | } |
58 | | #else |
59 | 0 | auto ret = sem_init(&sem_, /*pshared*/ 0, /*value*/ 0); |
60 | 0 | if (ret != 0) { |
61 | 0 | perror("sem_init"); |
62 | 0 | return false; |
63 | 0 | } |
64 | 0 | #endif |
65 | 0 | return true; |
66 | 0 | } |
67 | | |
68 | 0 | bool Semaphore::close() { |
69 | | #ifdef __APPLE__ |
70 | | if (sem_close(semPtr_) != 0) { |
71 | | perror("sem_close"); |
72 | | return false; |
73 | | } |
74 | | #else |
75 | 0 | if (sem_destroy(&sem_) != 0) { |
76 | 0 | perror("sem_destroy"); |
77 | 0 | return false; |
78 | 0 | } |
79 | 0 | #endif |
80 | 0 | return true; |
81 | 0 | } |
82 | | |
83 | 0 | bool Semaphore::notifyOne() { |
84 | 0 | int ret = sem_post(getSemaphorePtr()); |
85 | 0 | if (ret != 0) { |
86 | 0 | perror("sem_post"); |
87 | 0 | return false; |
88 | 0 | } |
89 | 0 | return true; |
90 | 0 | } |
91 | | |
92 | 0 | bool Semaphore::wait() { |
93 | 0 | int ret = sem_wait(getSemaphorePtr()); |
94 | 0 | if (ret != 0) { |
95 | 0 | perror("sem_wait"); |
96 | 0 | return false; |
97 | 0 | } |
98 | 0 | return true; |
99 | 0 | } |
100 | | |
101 | | } // namespace hermes |
102 | | |
103 | | #endif // not _WINDOWS |