Skip to main content

flag_bearer_core/
lib.rs

1#![no_std]
2#![deny(unsafe_code)]
3
4/// The trait defining how semaphores behave.
5///
6/// The usage of this state is as follows:
7/// ```
8/// # use flag_bearer_core::SemaphoreState;
9/// # use std::sync::Mutex;
10/// fn get_permit<S: SemaphoreState>(s: &Mutex<S>, mut params: S::Params) -> S::Permit {
11///     loop {
12///         let mut s = s.lock().unwrap();
13///         match s.acquire(params) {
14///             Ok(permit) => break permit,
15///             Err(p) => params = p,
16///         }
17///
18///         // sleep/spin/yield until time to try again
19///     }
20/// }
21///
22/// fn return_permit<S: SemaphoreState>(s: &Mutex<S>, permit: S::Permit) {
23///     s.lock().unwrap().release(permit);
24/// }
25/// ```
26pub trait SemaphoreState {
27    /// What type is used to request permits.
28    ///
29    /// An example of this could be `usize` for a counting semaphore,
30    /// if you want to support `acquire_many` type requests.
31    type Params;
32
33    /// The type representing the current permit allocation.
34    ///
35    /// If you have a counting semaphore, this could be the number
36    /// of permits acquired. If this is more like a connection pool,
37    /// this could be a specific object allocation.
38    type Permit;
39
40    /// Acquire a permit given the params.
41    ///
42    /// If a permit could not be acquired with the params, return an error with the
43    /// original params back.
44    ///
45    /// # Panics
46    ///
47    /// This method should not panic. If it does, the params are lost and `self` may be
48    /// left half-updated, so the semaphore is *poisoned*: it stops handing out permits.
49    /// A blocking `acquire` then panics, while `try_acquire` reports the poison via its
50    /// error type.
51    fn acquire(&mut self, params: Self::Params) -> Result<Self::Permit, Self::Params>;
52
53    /// Return the permit back to the semaphore.
54    ///
55    /// Note: This is not guaranteed to be called for every acquire call.
56    /// Permits can be modified or forgotten, or created at will.
57    fn release(&mut self, permit: Self::Permit);
58}