How to actively poison a Mutex without panicking

Hi,

is it possible to mark a std::sync::Mutex as poisoned without spawning a new thread for the purpose of panicking it?

Not with the existing public API, as far as I can tell. Though you don’t need a full new thread, since you can also do catch_unwind within the existing thread. [That’s probably still going to be a bit more expensive than what would actually be necessary to just set the poison state, as unwind paths are generally very much non-optimized, but at least way cheaper than spawning a new thread for this purpose.]

let m = std::sync::Mutex::new(42);
let l = m.lock().unwrap();
let _: Result<_, _> = std::panic::catch_unwind(|| {
    let _l = l; // capture l, so it's dropped with the unwind below
    std::panic::resume_unwind(Box::new(())); // "resume_unwind" skips the panic message
});
m.lock().unwrap_err(); // test that it's indeed poisoned

(playground)

1 Like

shouldn't i be getting a panic on the last line when I run this?

edit: ah nevermind, it's unwrap_err, not unwrap.

thank you :slight_smile:

No, the .unwrap_err() call only panics when the mutex was not poisoned. It doesn't panic because the mutex is correctly poisoned.

1 Like