1 /**
2     Semaphores
3 
4     Copyright:
5         Copyright © 2023-2025, Kitsunebi Games
6         Copyright © 2023-2025, Inochi2D Project
7     
8     License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
9     Authors:   Luna Nielsen
10 */
11 module nulib.threading.semaphore;
12 import nulib.threading.internal.semaphore;
13 import numem;
14 
15 /**
16     A sempahore.
17 */
18 class Semaphore : NuObject {
19 private:
20 @nogc:
21     NativeSemaphore semaphore_;
22 
23 public:
24 
25     /**
26         The native implementation defined handle of the semaphore.
27     */
28     final @property NativeSemaphore nativeHandle() => semaphore_;
29 
30     /// Destructor
31     ~this() {
32         nogc_delete(semaphore_);
33     }
34 
35     /**
36         Constructs a new Mutex.
37     */
38     this(uint count = 0) {
39         this.semaphore_ = NativeSemaphore.create(count);
40         enforce(semaphore_, "Semaphore is not supported on this platform.");
41     }
42 
43     /**
44         Signals the semaphore.
45 
46         Note:
47             Control is not transferred to the waiter.
48     */
49     void signal() {
50         semaphore_.signal();
51     }
52 
53     /**
54         Suspends the thread until the semaphore is signaled,
55         or the timeout is reached.
56 
57         Params:
58             timeout =   Timeout in miliseconds to block the 
59                         calling thread before giving up.
60 
61         Returns:
62             $(D true) if the semaphore was signaled in time,
63             $(D false) otherwise.
64     */
65     bool await(ulong timeout = 0) {
66         return semaphore_.await(timeout);
67     }
68 
69     /**
70         Checks if the semaphore is signalled then
71         awaits on it if is.
72 
73         Returns:
74             $(D true) if the semaphore was signalled,
75             $(D false) otherwise.
76     */
77     bool tryAwait() {
78         return semaphore_.tryAwait();
79     }
80 }
81 
82 @("signal and await")
83 unittest {
84     Semaphore s = nogc_new!Semaphore();
85     s.signal();
86     assert(s.tryAwait());
87     nogc_delete(s);
88 }