While it is possible to ignore the poisoning of a Mutex with lock.lock().unwrap_or_else(|e| e.into_inner()), as far as I can tell there isn't any way to mark a mutex as un-poisoned. This means that even if you see that the lock is poisoned, and then ignore the existing value, and replace it with a new value, the mutex continues to be poisoned forever.
I have a situation where in one usage of the lock, if it is poisoned I want to recover by replacing the contents of the mutex, but in another usage, if it is poisoned, I want to panic.
I propose adding an API to mark a poisoned Mutex as unpoisoned, probably as an API on PoisonError.
A method on MutexGuard seems more reasonable since that gives you the ability to inspect the data before deciding whether to unpoison it. You could probably just go ahead and PR this. It's pretty trivial to implement:
I’m curious why atomics are used in the first place and the poisoning information doesn’t just live in the UnsafeCell together with the payload.
Edit: AFAIK modification of the poisoning state only happens when panicking while holding mutable access, and AFAICT, reading the poisoning information … actually, now that I look at the API again, I think the Mutex::is_poisoned method might be only reason why atomics are used. Otherwise, it only becomes relevant for the result of lock calls, when the Mutex is already locked. The same holds for RwLock, where the lock will already be acquired (mutably or immutably) before poisoning is checked.
Edit2: On that note, Relaxed ordering for unpoisoning should be completely fine.
Edit3: And a similar method on RwLockWriteGuard is probably a good idea. In both cases, one could also debate additional methods on the (write-) guards for
checking whether or not it’s currently poisoned (even though that information is also available from the result of locking); and
manually adding poison without needing to use a panic.
Yes, it's safe. Mutex poisoning is similar to (and related to) "unwind safety" which is - despite its name - a concept thats not related to "safe vs. unsafe" code, but instead often said to being similar to just a lint.
Edit: The only contrived example I can come up with where Mutex unpoisoning might be problematic is: Unsafe code that uses Mutexes and somehow relies on a poisoned Mutex never becoming unpoisoned, yet it also hands out a MutexGuard (or a shared reference to the Mutex itself) to external/untrusted (safe) code which would, with this API change, then gain the ability unpoison a Mutex that’s never supposed to be unpoisoned.