Coverage Report

Created: 2023-02-22 06:51

/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