pub struct PairLock<T> { /* private fields */ }
Expand description
A reader-writer lock with wait-free reads.
Does not have poisoning.
§Examples
let ac = Arc::new(PairLock::new_arc(load_config()));
let ac2 = ac.clone();
thread::spawn(move|| {
loop {
use_config(ac2.get());;
}
});
loop {
thread::sleep(Duration::from_secs(60));
ac.set(Arc::new(load_config()));
}
Implementations§
Source§impl<T> PairLock<T>
impl<T> PairLock<T>
Sourcepub fn with_default(init: T) -> Selfwhere
T: Default,
pub fn with_default(init: T) -> Selfwhere
T: Default,
Creates a new PairLock
with init
as the active value
and T
’s default value as the inactive.
Sourcepub fn with_clone(init: T) -> Selfwhere
T: Clone,
pub fn with_clone(init: T) -> Selfwhere
T: Clone,
Creates a new PairLock
with init
as the active value
and its .clone()
as the inactive.
Sourcepub fn view<F: FnOnce(&T) -> R, R>(&self, viewer: F) -> R
pub fn view<F: FnOnce(&T) -> R, R>(&self, viewer: F) -> R
View the active value of this PairLock
inside a closure.
Views should be short-lived to avoid blocking subsequent updates.
Reads must be performed inside a closure, because preventing memory
unsafety in the face of repeated mem::forget()
s of a read guard is
non-trivial.
Will never block in any way, and should run in constant time.
Sourcepub fn get_clone(&self) -> Twhere
T: Clone,
pub fn get_clone(&self) -> Twhere
T: Clone,
Returns a clone of the active value.
Will never block in any way, and should run in constant time.
Sourcepub fn update(&self) -> UpdateGuard<'_, T>
pub fn update(&self) -> UpdateGuard<'_, T>
Locks the inactive value, giving exclusive access to it through a RAII guard that will make it active when the guard is dropped.
Will block the thread waiting for reads of the inactive value or other updates to finish.
Panicing while holding the guard does not poison the lock.
§Examples
Using the lock as a counter
let counter = PairLock::with_default(1);
let mut guard = counter.update();
*guard = UpdateGuard::active(&guard) + 1;
drop(guard);
assert_eq!(counter.read(), 2);
Reusing an allocation while updating
let lock = PairLock::with_default(vec!["foo","bar"]);
let mut guard = lock.update();
{
let (mutable, active) = UpdateGuard::both(&mut guard);
mutable.clone_from(active);
mutable.push("baz");
}
drop(guard);
lock.view(|v| assert_eq!(v[..], ["foo","bar","baz"][..]) );
Doing nothing with the guard, and still changing the value of the lock:
let lock = PairLock::new("foo", "bar");
assert_eq!(lock.read(), "foo");
let _ = lock.update();
assert_eq!(lock.read(), "bar");
Sourcepub fn try_update(&self) -> Result<UpdateGuard<'_, T>, TryUpdateError>
pub fn try_update(&self) -> Result<UpdateGuard<'_, T>, TryUpdateError>
Attempts to lock the inactive value, giving exclusive access to it through a RAII guard that will make it active when the guard is dropped.
§Errors
Returns an error instead of blocking the thread.
The error tells which phase of aquiring the update lock that failed.
§Examples
let pl = PairLock::new(String::new(), String::new());
let _guard = pl.try_update().unwrap();
assert_eq!(pl.try_update(), Err(TryUpdateError::OtherUpdate));
Sourcepub fn set(&self, value: T) -> T
pub fn set(&self, value: T) -> T
Stores a new value in the PairLock
,
returning the previously inactive value.
Will block if another update/replace/set is in progress. if there are reads of the second last value that haven’t finished yet.
Sourcepub fn into_inner(self) -> (T, T)
pub fn into_inner(self) -> (T, T)
Consumes the PairLock
and returns the active and inactive values.
§Examples
let lock = PairLock::new(true, false);
let (active, inactive) = lock.into_inner();
Sourcepub fn get_mut_both(&mut self) -> (&mut T, &mut T)
pub fn get_mut_both(&mut self) -> (&mut T, &mut T)
Given exclusive access this method returns mutable references to both the active and inactive value.
§Examples
let mut lock = PairLock::new(true, false);
let (&mut active, &mut inactive) = lock.get_mut_both();
Sourcepub fn get_mut_active(&mut self) -> &mut T
pub fn get_mut_active(&mut self) -> &mut T
Given exclusive access this method returns a mutable reference to the active value.
Sourcepub fn get_mut_inactive(&mut self) -> &mut T
pub fn get_mut_inactive(&mut self) -> &mut T
Given exclusive access this method returns a mutable reference to the inactive value.
Trait Implementations§
impl<T: Send> Send for PairLock<T>
impl<T: Send + Sync> Sync for PairLock<T>
T
must be Send
because a shared reference can replace stored values.
Auto Trait Implementations§
impl<T> !Freeze for PairLock<T>
impl<T> !RefUnwindSafe for PairLock<T>
impl<T> Unpin for PairLock<T>where
T: Unpin,
impl<T> UnwindSafe for PairLock<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)