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}