mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-11-28 13:09:10 -05:00
wrap Mutex and Condvar to handle poison
This centralizes a major source of `.unwrap()` throughout the code, and one that would otherwise grow with upcoming changes. The new error message should be more clear.
This commit is contained in:
@@ -14,3 +14,64 @@ pub use crate::error::{Error, ErrorBuilder, ErrorKind, ResultExt};
|
||||
pub use ahash::RandomState;
|
||||
pub type FastHashMap<K, V> = std::collections::HashMap<K, V, ahash::RandomState>;
|
||||
pub type FastHashSet<K> = std::collections::HashSet<K, ahash::RandomState>;
|
||||
|
||||
const NOT_POISONED: &str =
|
||||
"not poisoned; this is a consequence of an earlier panic while holding this mutex; see logs.";
|
||||
|
||||
/// [`std::sync::Mutex`] wrapper which always panics on encountering poison.
|
||||
#[derive(Default)]
|
||||
pub struct Mutex<T>(std::sync::Mutex<T>);
|
||||
|
||||
impl<T> Mutex<T> {
|
||||
#[inline]
|
||||
pub const fn new(value: T) -> Self {
|
||||
Mutex(std::sync::Mutex::new(value))
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[inline]
|
||||
pub fn lock(&self) -> std::sync::MutexGuard<T> {
|
||||
self.0.lock().expect(NOT_POISONED)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[inline]
|
||||
pub fn into_inner(self) -> T {
|
||||
self.0.into_inner().expect(NOT_POISONED)
|
||||
}
|
||||
}
|
||||
|
||||
/// [`std::sync::Condvar`] wrapper which always panics on encountering poison.
|
||||
#[derive(Default)]
|
||||
pub struct Condvar(std::sync::Condvar);
|
||||
|
||||
impl Condvar {
|
||||
#[inline]
|
||||
pub const fn new() -> Self {
|
||||
Self(std::sync::Condvar::new())
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[inline]
|
||||
pub fn wait_timeout_while<'a, T, F>(
|
||||
&self,
|
||||
guard: std::sync::MutexGuard<'a, T>,
|
||||
dur: std::time::Duration,
|
||||
condition: F,
|
||||
) -> (std::sync::MutexGuard<'a, T>, std::sync::WaitTimeoutResult)
|
||||
where
|
||||
F: FnMut(&mut T) -> bool,
|
||||
{
|
||||
self.0
|
||||
.wait_timeout_while(guard, dur, condition)
|
||||
.expect(NOT_POISONED)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Condvar {
|
||||
type Target = std::sync::Condvar;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user