flag_bearer_core/lib.rs
1//! Core traits for the `flag-bearer` family of crates.
2//!
3//! It's expected that you consume `flag-bearer` crate directly, but this is
4//! exposed for flexibilty of queue implementations.
5
6#![no_std]
7#![deny(unsafe_code)]
8
9/// The trait defining how semaphores behave.
10///
11/// The usage of this state is as follows:
12/// ```
13/// # use flag_bearer_core::SemaphoreState;
14/// # use std::sync::Mutex;
15/// fn get_permit<S: SemaphoreState>(s: &Mutex<S>, mut params: S::Params) -> S::Permit {
16/// loop {
17/// let mut s = s.lock().unwrap();
18/// match s.acquire(params) {
19/// Ok(permit) => break permit,
20/// Err(p) => params = p,
21/// }
22///
23/// // sleep/spin/yield until time to try again
24/// }
25/// }
26///
27/// fn return_permit<S: SemaphoreState>(s: &Mutex<S>, permit: S::Permit) {
28/// s.lock().unwrap().release(permit);
29/// }
30/// ```
31pub trait SemaphoreState {
32 /// What type is used to request permits.
33 ///
34 /// An example of this could be `usize` for a counting semaphore,
35 /// if you want to support `acquire_many` type requests.
36 type Params;
37
38 /// The type representing the current permit allocation.
39 ///
40 /// If you have a counting semaphore, this could be the number
41 /// of permits acquired. If this is more like a connection pool,
42 /// this could be a specific object allocation.
43 type Permit;
44
45 /// Acquire a permit given the params.
46 ///
47 /// # Errors
48 ///
49 /// If a permit could not be acquired with the given params,
50 /// return an error and the original params back.
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}