Plasma Engine  2.0
Loading...
Searching...
No Matches
Semaphore_Posix.h
1#include <Foundation/FoundationInternal.h>
2PL_FOUNDATION_INTERNAL_HEADER
3
4#include <Foundation/Threading/Semaphore.h>
5
6#include <Foundation/Strings/StringBuilder.h>
7
8#include <fcntl.h>
9#include <semaphore.h>
10#include <sys/stat.h>
11
12PL_WARNING_PUSH()
13// On OSX sem_destroy and sem_init are deprecated
14PL_WARNING_DISABLE_CLANG("-Wdeprecated-declarations")
15
16plSemaphore::plSemaphore() = default;
17
19{
20 if (m_hSemaphore.m_pNamedOrUnnamed != nullptr)
21 {
22 if (m_hSemaphore.m_pNamed != nullptr)
23 {
24 sem_close(m_hSemaphore.m_pNamed);
25 }
26 else
27 {
28 sem_destroy(&m_hSemaphore.m_Unnamed);
29 }
30 }
31}
32
33plResult plSemaphore::Create(plUInt32 uiInitialTokenCount, plStringView sSharedName /*= nullptr*/)
34{
35 if (sSharedName.IsEmpty())
36 {
37 // create an unnamed semaphore
38
39 if (sem_init(&m_hSemaphore.m_Unnamed, 0, uiInitialTokenCount) != 0)
40 {
41 return PL_FAILURE;
42 }
43
44 m_hSemaphore.m_pNamedOrUnnamed = &m_hSemaphore.m_Unnamed;
45 }
46 else
47 {
48 // create a named semaphore
49
50 // documentation is unclear about access rights, just throwing everything at it for good measure
52 m_hSemaphore.m_pNamed = sem_open(sSharedName.GetData(tmp), O_CREAT | O_EXCL, S_IRWXU | S_IRWXO | S_IRWXG, uiInitialTokenCount);
53
54 if (m_hSemaphore.m_pNamed == nullptr)
55 {
56 return PL_FAILURE;
57 }
58
59 m_hSemaphore.m_pNamedOrUnnamed = m_hSemaphore.m_pNamed;
60 }
61
62 return PL_SUCCESS;
63}
64
66{
67 PL_ASSERT_DEV(!sSharedName.IsEmpty(), "Name of semaphore to open mustn't be empty.");
68
69 // open a named semaphore
70
72 m_hSemaphore.m_pNamed = sem_open(sSharedName.GetData(tmp), 0);
73
74 if (m_hSemaphore.m_pNamed == nullptr)
75 {
76 return PL_FAILURE;
77 }
78
79 m_hSemaphore.m_pNamedOrUnnamed = m_hSemaphore.m_pNamed;
80
81 return PL_SUCCESS;
82}
83
85{
86 PL_VERIFY(sem_wait(m_hSemaphore.m_pNamedOrUnnamed) == 0, "Semaphore token acquisition failed.");
87}
88
90{
91 PL_VERIFY(sem_post(m_hSemaphore.m_pNamedOrUnnamed) == 0, "Returning a semaphore token failed, most likely due to a AcquireToken() / ReturnToken() mismatch.");
92}
93
95{
96 // documentation is unclear whether one needs to check errno, or not
97 // assuming that this will return 0 only when trywait got a token
98
99 if (sem_trywait(m_hSemaphore.m_pNamedOrUnnamed) == 0)
100 return PL_SUCCESS;
101
102 return PL_FAILURE;
103}
104
105PL_WARNING_POP()
A semaphore is used to synchronize threads, similar to a mutex (see plMutex).
Definition Semaphore.h:17
void ReturnToken()
Returns a single token. If another thread is currently waiting for a token, this will wake it up.
Definition Semaphore_Posix.h:89
plResult TryAcquireToken(plTime timeout=plTime::MakeZero())
Same as AcquireToken() but returns immediately with PL_FAILURE, if currently not tokens are available...
Definition Semaphore_Posix.h:94
plResult Create(plUInt32 uiInitialTokenCount=0, plStringView sSharedName=plStringView())
Attempts to create a new semaphore with an initial number of available tokens.
Definition Semaphore_Posix.h:33
void AcquireToken()
Waits until a token is available and acquires it.
Definition Semaphore_Posix.h:84
plResult Open(plStringView sSharedName)
Attempts to open an existing named semaphore.
Definition Semaphore_Posix.h:65
plStringBuilder is a class that is meant for creating and modifying strings.
Definition StringBuilder.h:35
plStringView represent a read-only sub-string of a larger string, as it can store a dedicated string ...
Definition StringView.h:34
const char * GetData(plStringBuilder &ref_sTempStorage) const
Returns the data as a zero-terminated string.
Definition StringView.cpp:15
bool IsEmpty() const
Returns whether the string is an empty string.
Definition StringView_inl.h:85
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54
The time class encapsulates a double value storing the time in seconds.
Definition Time.h:12