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}