os_sync/sem/
mod.rs

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