-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Open
Description
Currently, if you are to use any of the locks provided by the standard library, you are forced to handle lock poisoning
use std::sync::*;
let hello = Mutex::new(2);
std::thread::scope(|s| {
s.spawn(|| {
let _guard = hello.lock();
panic!("Ups!");
});
// May return `Err`, if `_guard` is obtained before `guard2`
let guard2: LockResult<MutexGuard<T>> = hello.lock();
})
Most of the time you aren't really interested in maneging these, so you're left with two options.
You can unwrap the result, hoping no previous holder has panicked.
use std::sync::*;
let hello = Mutex::new(2);
std::thread::scope(|s| {
s.spawn(|| {
let _guard = hello.lock();
panic!("Ups!");
});
// May panic, if `_guard` is obtained before `guard2`
let guard2: MutexGuard<T> = hello.lock().unwrap();
})
Or you can force the error to return you the lock
use std::sync::*;
let hello = Mutex::new(2);
std::thread::scope(|s| {
s.spawn(|| {
let _guard = hello.lock();
panic!("Ups!");
});
// Never panics
let guard2: MutexGuard<T> = match hello.lock() {
Ok(x) => x,
Err(e) => e.into_inner()
};
})
Ideally, you should be using the last example if you aren't interested in maneging poisonous locks, but having to make the same match expression every time you want to lock is very cumbersome, so perhaps we should add a method that makes the lock without checking if it's poisoned.
use std::sync::*;
let hello = Mutex::new(2);
std::thread::scope(|s| {
s.spawn(|| {
let _guard = hello.lock();
panic!("Ups!");
});
// Never panics (name is an example, and I'm sure a better one exists)
let guard2: MutexGuard<T> = hello.lock_deep();
})
Metadata
Metadata
Assignees
Labels
No labels