pub struct Gate { /* private fields */ }Expand description
Gate is a synchronization primitive that blocks tasks from entering a critical section until
they are allowed to do so.
Implementations§
Source§impl Gate
impl Gate
Sourcepub fn reset(&self) -> Option<State>
pub fn reset(&self) -> Option<State>
Resets the Gate to its initial state if it is not in a Controlled
state.
Returns the previous state of the Gate.
§Examples
use saa::Gate;
use saa::gate::State;
let gate = Gate::default();
assert_eq!(gate.reset(), None);
gate.seal();
assert_eq!(gate.reset(), Some(State::Sealed));Sourcepub fn permit(&self) -> Result<usize, State>
pub fn permit(&self) -> Result<usize, State>
Permits waiting tasks to enter the Gate if the Gate is in a
Controlled state.
Returns the number of permitted tasks.
§Errors
Returns an Error if the Gate is not in a Controlled state.
§Examples
use std::sync::Arc;
use std::thread;
use saa::Gate;
use saa::gate::State;
let gate = Arc::new(Gate::default());
let gate_clone = gate.clone();
let thread = thread::spawn(move || {
assert_eq!(gate_clone.enter_sync(), Ok(State::Controlled));
});
loop {
if gate.permit() == Ok(1) {
break;
}
}
thread.join().unwrap();Sourcepub fn reject(&self) -> Result<usize, State>
pub fn reject(&self) -> Result<usize, State>
Rejects waiting tasks from entering the Gate if the Gate is in a
Controlled state.
Returns the number of rejected tasks.
§Errors
Returns an Error if the Gate is not in a Controlled state.
§Examples
use std::sync::Arc;
use std::thread;
use saa::Gate;
use saa::gate::Error;
let gate = Arc::new(Gate::default());
let gate_clone = gate.clone();
let thread = thread::spawn(move || {
assert_eq!(gate_clone.enter_sync(), Err(Error::Rejected));
});
loop {
if gate.reject() == Ok(1) {
break;
}
}
thread.join().unwrap();Sourcepub fn open(&self) -> (State, usize)
pub fn open(&self) -> (State, usize)
Opens the Gate to allow any tasks to enter it.
Returns the number of tasks that were waiting to enter it.
§Examples
use std::sync::atomic::Ordering::Relaxed;
use saa::Gate;
use saa::gate::State;
let gate = Gate::default();
assert_eq!(gate.state(Relaxed), State::Controlled);
let (prev_state, count) = gate.open();
assert_eq!(prev_state, State::Controlled);
assert_eq!(count, 0);
assert_eq!(gate.state(Relaxed), State::Open);Sourcepub fn seal(&self) -> (State, usize)
pub fn seal(&self) -> (State, usize)
Seals the Gate to disallow tasks from entering.
Returns the previous state of the Gate and the number of tasks that were waiting to
enter the Gate.
§Examples
use std::sync::atomic::Ordering::Relaxed;
use saa::Gate;
use saa::gate::State;
let gate = Gate::default();
let (prev_state, count) = gate.seal();
assert_eq!(prev_state, State::Controlled);
assert_eq!(count, 0);
assert_eq!(gate.state(Relaxed), State::Sealed);Sourcepub async fn enter_async(&self) -> Result<State, Error>
pub async fn enter_async(&self) -> Result<State, Error>
Enters the Gate asynchronously.
This method does not return until Gate::open, Gate::permit, Gate::reject, or
Gate::seal is invoked afterwards by other tasks, or the current task is cancelled.
Returns the current state of the Gate.
§Errors
Returns an Error if it failed to enter the Gate.
§Examples
use futures::future;
use saa::Gate;
let gate = Gate::default();
let a = async {
assert!(gate.enter_async().await.is_ok());
};
let b = async {
gate.permit();
};
future::join(a, b);Sourcepub fn enter_sync(&self) -> Result<State, Error>
pub fn enter_sync(&self) -> Result<State, Error>
Enters the Gate synchronously.
This method does not return until Gate::open, Gate::permit, Gate::reject, or
Gate::seal is invoked afterwards by other tasks.
Returns the current state of the Gate.
§Errors
Returns an Error if it failed to enter the Gate.
§Examples
use std::sync::Arc;
use std::thread;
use saa::Gate;
use saa::gate::State;
let gate = Arc::new(Gate::default());
let gate_clone = gate.clone();
let thread_1 = thread::spawn(move || {
assert_eq!(gate_clone.enter_sync(), Ok(State::Controlled));
});
let gate_clone = gate.clone();
let thread_2 = thread::spawn(move || {
assert_eq!(gate_clone.enter_sync(), Ok(State::Controlled));
});
let mut count = 0;
while count != 2 {
if let Ok(n) = gate.permit() {
count += n;
}
}
thread_1.join().unwrap();
thread_2.join().unwrap();Sourcepub async fn enter_async_with<F: FnOnce()>(
&self,
begin_wait: F,
) -> Result<State, Error>
pub async fn enter_async_with<F: FnOnce()>( &self, begin_wait: F, ) -> Result<State, Error>
Enters the Gate asynchronously with a wait callback.
Returns the current state of the Gate. The callback is invoked when the task starts
waiting.
§Errors
Returns an Error if it failed to enter the Gate.
§Examples
use futures::future;
use saa::Gate;
let gate = Gate::default();
let a = async {
let mut wait = false;
assert!(gate.enter_async_with(|| wait = true).await.is_ok());
};
let b = async {
gate.permit();
};
future::join(a, b);Sourcepub fn enter_sync_with<F: FnOnce()>(
&self,
begin_wait: F,
) -> Result<State, Error>
pub fn enter_sync_with<F: FnOnce()>( &self, begin_wait: F, ) -> Result<State, Error>
Enters the Gate synchronously with a wait callback.
Returns the current state of the Gate. The callback is invoked when the task starts
waiting.
§Errors
Returns an Error if it failed to enter the Gate.
§Examples
use std::sync::Arc;
use std::thread;
use saa::Gate;
use saa::gate::State;
let gate = Arc::new(Gate::default());
let gate_clone = gate.clone();
let thread_1 = thread::spawn(move || {
let mut wait = false;
assert_eq!(gate_clone.enter_sync_with(|| wait = true), Ok(State::Controlled));
});
let gate_clone = gate.clone();
let thread_2 = thread::spawn(move || {
let mut wait = false;
assert_eq!(gate_clone.enter_sync_with(|| wait = true), Ok(State::Controlled));
});
let mut count = 0;
while count != 2 {
if let Ok(n) = gate.permit() {
count += n;
}
}
thread_1.join().unwrap();
thread_2.join().unwrap();Sourcepub fn register_pager<'g>(
&'g self,
pager: &mut Pin<&mut Pager<'g, Self>>,
is_sync: bool,
) -> bool
pub fn register_pager<'g>( &'g self, pager: &mut Pin<&mut Pager<'g, Self>>, is_sync: bool, ) -> bool
Registers a Pager to allow it to get a permit to enter the Gate remotely.
is_sync indicates whether the Pager will be polled asynchronously (false) or
synchronously (true).
Returns false if the Pager was already registered.
§Examples
use std::pin::pin;
use std::sync::Arc;
use std::thread;
use saa::{Gate, Pager};
use saa::gate::State;
let gate = Arc::new(Gate::default());
let mut pinned_pager = pin!(Pager::default());
assert!(gate.register_pager(&mut pinned_pager, true));
assert!(!gate.register_pager(&mut pinned_pager, true));
let gate_clone = gate.clone();
let thread = thread::spawn(move || {
assert_eq!(gate_clone.permit(), Ok(1));
});
thread.join().unwrap();
assert_eq!(pinned_pager.poll_sync(), Ok(State::Controlled));