Should I unwrap() a mutex lock?

I'm cleaning all unwraps of my code so anyone using it as a library won't have random panics on the entire application for something wrong in my library.

However, for Mutex.lock() I'm in doubt. It's not easy to handle errors instead of unwrapping, and a mutex unwraps when it's poisoned, so it should be the right thing to panic?

1 Like

Yes. You get a poisoned lock when some other piece of code triggered a panic while holding the lock. If this happens the world is probably already in a bad state so your best option is to crash the program asap.

It's possible to work with poisoned data and all Rust code is expected to maintain memory-safety in the face of panics, but it could mean some of the assumptions that the rest of your code makes are no longer valid.

For example, let's say you store cached items in a Arc<Mutex<Vec<CachedItem>>> sorted by timestamp and adding new data to the cache is a case of pushing on to the end and calling cache.sort(). If the sort fails midway through because of a dodgy PartialEq implementation then you'll drop the lock while unwinding, leaving a partially sorted cache behind. The next time you try to use the cache, you might find that asking for the most recent value with a particular key doesn't actually give you the most recent value and the end user might refresh their screen and say "wtf, I thought I just changed that field".

I don't see any value in propagating poisoning errors because the only way you'll ever deal with them is by a) passing the error up with ? and killing the program, b) ignoring the poison and using the value anyway, or c) fixing the possibly broken invariant then and there (i.e. by re-sorting your cache). Using unwrap() on the error is just like option "a", except we aren't forcing every function up the call stack to return a Result<_, Error> containing an error that can't be resolved.

6 Likes

handling poison is cumbersome in programing, in most of cases, "panic" in one thread will lead to crash. you can check parking_lot if you don't want to use unwrap or handle poison error

2 Likes

releasing the lock on panic seems something very important to do, why doesn't Rust's Mutex do it? This library claims to be faster while doing this.

It does release the lock on panic. It just also sets a poison flag on the mutex to signal that the contents may be in an inconsistent state. You can ignore the poison flag by inspecting the error value.

To be clear, inconsistent is with respect to your own code and your own assumptions about the value. The mutex itself is fine.

7 Likes

but why is that on parking_lot I don't have to worry about these inconsistencies?

The parking_lot crate chose not to include poisoning as a feature.

https://github.com/Amanieu/parking_lot/issues/44

Poisoning is not necessary for safety. It's just a tool that Rust provides that is intended to help you recover from panics.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.