add a parking lot impl
This commit is contained in:
40
src/busy_lot.rs
Normal file
40
src/busy_lot.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
/// Shared, lock-free counter of active jobs.
|
||||
/// Cloning is cheap (Arc); dropping a ticket auto-decrements.
|
||||
#[derive(Clone)]
|
||||
pub struct BusyLot {
|
||||
inner: Arc<AtomicUsize>,
|
||||
}
|
||||
|
||||
/// RAII ticket returned from `BusyLot::park()`.
|
||||
/// When the ticket is dropped (even on panic) the lot counter goes down.
|
||||
pub struct Ticket {
|
||||
lot: BusyLot,
|
||||
}
|
||||
|
||||
impl BusyLot {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
inner: Arc::new(AtomicUsize::new(0)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Takes a parking space and returns a ticket.
|
||||
pub fn park(&self) -> Ticket {
|
||||
self.inner.fetch_add(1, Ordering::AcqRel);
|
||||
Ticket { lot: self.clone() }
|
||||
}
|
||||
|
||||
/// `true` if at least one ticket is still parked.
|
||||
pub fn is_busy(&self) -> bool {
|
||||
self.inner.load(Ordering::Acquire) != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Ticket {
|
||||
fn drop(&mut self) {
|
||||
self.lot.inner.fetch_sub(1, Ordering::AcqRel);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user