Skip to main content

padlock/
mutex.rs

1use std::sync::{
2    Mutex,
3    MutexGuard,
4    atomic::spin_loop_hint
5};
6
7/// Aquire a Mutex lock, passing the lock to the lambda.
8/// The lock is released when the lambda finishes.
9/// This function returns whatever the lambda returns,
10/// allowing you to extract data from a lock without having
11/// to worry about releasing the lock.
12///
13/// Read:
14/// ```ignore
15/// let extracted = padlock::mutex_lock(&arc_mutex_var, |lock| lock.clone());
16/// ```
17///
18/// Write:
19/// ```ignore
20/// padlock::mutex_lock(&arc_mutex_var, |lock| *lock = new_value);
21/// ```
22pub fn mutex_lock<T, F, R>(m: &Mutex<T>, f: F) -> R
23    where F: FnOnce(&mut T) -> R {
24
25    let r: R;
26
27    loop {
28
29        match m.try_lock().as_mut() {
30
31            Ok(mut lock) => {
32                r = f(&mut lock);
33                drop(lock);
34                break;
35            },
36
37            Err(_) => spin_loop_hint()
38
39        }
40
41    }
42
43    r
44
45}
46
47/// Get the MutexGuard directly, aquired with a spinlock.
48///
49/// Important: Don't forget to drop the lock! Locks release
50/// themselfs when they go out of scope but the faster you
51/// drop it, the faster other threads get access.
52pub fn get_mutex_lock<T>(m: &Mutex<T>) -> MutexGuard<'_, T> {
53
54    loop {
55
56        match m.try_lock() {
57            Ok(lock) => return lock,
58            Err(_) => spin_loop_hint()
59        }
60
61    }
62
63}