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 }