essential_lock/
lib.rs

1//! # Lock
2//! This crate is a simple wrapper around sync mutexes that makes it impossible to
3//! hold a lock over an await.
4//!
5//! It also makes it a lot clearer where the bounds of the lock are which helps make deadlocks easier to debug
6//! as a deadlock would require having the call to `apply` more than once on the stack.
7#![deny(missing_docs)]
8#![deny(unsafe_code)]
9
10/// A lock that is guaranteed to be released before an await.
11pub struct StdLock<T> {
12    data: std::sync::Mutex<T>,
13}
14
15impl<T> StdLock<T> {
16    /// Create a new lock with the given data.
17    pub fn new(data: T) -> Self {
18        StdLock {
19            data: std::sync::Mutex::new(data),
20        }
21    }
22
23    /// Apply a function to the data in the lock.
24    pub fn apply<U>(&self, f: impl FnOnce(&mut T) -> U) -> U {
25        f(&mut self.data.lock().expect("Mutex was poisoned"))
26    }
27}