1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
//!Semaphore primitive #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))] mod posix; #[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))] pub use posix::Sem; #[cfg(windows)] mod win32; #[cfg(windows)] pub use win32::Sem; #[cfg(any(target_os = "macos", target_os = "ios"))] mod mac; #[cfg(any(target_os = "macos", target_os = "ios"))] pub use mac::Sem; ///Describes Semaphore interface /// ///This primitive provides access to single integer that can be decremented using signal ///and incremented using wait pub trait Semaphore: Sized { ///Creates new instance, returning None on inability to do so. /// ///`init` is initial value for the semaphore fn new(init: u32) -> Option<Self>; ///Decrements self, returning immediately if it was signaled. /// ///Otherwise awaits for `signal` fn wait(&self); ///Attempts to decrement self, returning whether self was signaled or not. /// ///Returns `true` if self was signaled /// ///Returns `false` otherwise fn try_wait(&self) -> bool; ///Attempts to decrement self within provided time, returning whether self was signaled or not. /// ///Returns `true` if self was signaled within specified `timeout` /// ///Returns `false` otherwise fn wait_timeout(&self, timeout: core::time::Duration) -> bool; ///Increments self, returning whether another thread has been woken as result. fn post(&self) -> bool; ///Increments self, waking any awaiting thread as result fn signal(&self); ///Gets semaphore's guard, which signal on drop. /// ///Before guard is created, function will await for semaphore to get decremented. fn lock(&self) -> SemaphoreGuard<'_, Self> { self.wait(); SemaphoreGuard { sem: self } } ///Attempts to acquire semaphore's guard, which signal on drop. /// ///If semaphore cannot be decremented at the current moment, returns `None` fn try_lock(&self) -> Option<SemaphoreGuard<'_, Self>> { match self.try_wait() { true => Some(SemaphoreGuard { sem: self, }), false => None, } } } ///[Semaphore](trait.Semaphore.html) guard /// ///Increments(signal) semaphore on drop. pub struct SemaphoreGuard<'a, T: Semaphore> { sem: &'a T, } impl<T: Semaphore> Drop for SemaphoreGuard<'_, T> { fn drop(&mut self) { self.sem.signal(); } }