musli_common/context/access.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
use core::cell::Cell;
/// Guarded access to some underlying state.
pub(crate) struct Access {
state: Cell<isize>,
}
impl Access {
pub(crate) fn new() -> Self {
Self {
state: Cell::new(0),
}
}
#[inline]
pub(crate) fn shared(&self) -> Shared<'_> {
let state = self.state.get();
if state > 0 {
panic!("Context is exclusively held")
}
if state == isize::MIN {
crate::system::abort();
}
self.state.set(state - 1);
Shared { access: self }
}
#[inline]
pub(crate) fn exclusive(&self) -> Exlusive<'_> {
let state = self.state.get();
if state != 0 {
panic!("Context is already in shared use")
}
if state == isize::MIN {
crate::system::abort();
}
self.state.set(1);
Exlusive { access: self }
}
}
/// A shared access to some underlying state.
pub(crate) struct Shared<'a> {
access: &'a Access,
}
impl Drop for Shared<'_> {
fn drop(&mut self) {
self.access.state.set(self.access.state.get() + 1);
}
}
/// An exclusive access to some underlying state.
pub(crate) struct Exlusive<'a> {
access: &'a Access,
}
impl Drop for Exlusive<'_> {
fn drop(&mut self) {
self.access.state.set(0);
}
}