hachyderm.io is one of the many independent Mastodon servers you can use to participate in the fediverse.
Hachyderm is a safe space, LGBTQIA+ and BLM, primarily comprised of tech industry professionals world wide. Note that many non-user account types have restrictions - please see our About page.

Administered by:

Server stats:

9.5K
active users

rain 🌦️

Never use Tokio mutexes. From a guide I'm in the middle of writing:

@rain ooof. I assume this applies to futures::lock::Mutex, too?...

@zkat Yes, looks like it. Basically async and mutexes just don't play along, because futures can always be cancelled (dropped) at any await point

@rain @zkat

Given a choice I'd reach for tokio's Mutex before futures::lock::Mutex -- they both have the same issue Rain describes (where if you drop them while invariants are violated, you get bugs later), but tokio's is at least fair (making starvation harder).

@rain @zkat shouldn’t the drop of the task imply a drop of the mutexguard?

@baloo @zkat Yes, the problem is that if invariants are violated in the middle of the critical section (very normal for mutexes) then the mutex silently unlocks and the invariants stay violated

@rain @zkat ha, good point! I was only looking for poisoned mutex

@rain @zkat removing the Unpin blanket implementation should make sure it can't cross await points right?

@baloo @zkat That would defeat the point of tokio mutexes though, if you don't want to cross await points then you can just use std mutexes

@rain I feel like the concept of a mutex just isn't as general in async rust and I wonder what new things we need instead.

Like, I'm using lilos mutexes heavily for the first time in a project right now, and having something like that is great for e.g. fair shared access to a driver. But I've had to make all my drivers cancel safe as a result.

Message-passing often winds up needing a heap to resolve ownership issues, ruling it out for me.

I feel like we need something new.

@rain yes, in general async sync primitives seem to be a sign of bugs. async state probably should only be held by one task or instead made into sync state. i have not deadlocked myself with sync primitives (in particular because of very limited critical section lengths) but i have dealt with async ones deadlocking which is also impossible to debug comparatively.

@rain I was also contemplating submitting a change to the tokio docs to stop suggesting parking_lot also, because the std mutex really is fine now for basically all use cases, and parking_lot may be only a slight improvement.

@leftpaddotpy @rain wasn't parking_lot one of the things they were considering merging into std?

@Lunaphied @rain yes but i think it got cancelled on account of the std mutexes getting plain old rewritten instead

@leftpaddotpy @rain huh, we'll have to look at the new implementation then. Honestly I thought std::Mutex was fairly decently written if simplistic

@leftpaddotpy Correct, the parking lot mutex should not be recommended because it doesn't do lock poisoning.

@leftpaddotpy @rain fully onboard with avoiding mutexen, but, does the std mutex still run the risk of blocking / sleeping the executor task? such a nightmare to debug when a dependency contains a lock that breaks the runtime.

@r @rain yes, but if you're holding a mutex for an appreciable period of time for a pure, no-io, task, that's a separate problem imo. In that case, the program design should probably be rethought to have a worker thread and message passing.

Another thought: a reason this could happen is deadlocking cross-task. But if you use std mutex, the guard is !Send so that's basically impossible to do since you cannot hold it over await points.

In the cases where I use them, they are very uncontended.

@rain Hm what are the alternatives? You obviously will never always have lock-free structures. Are Rwlock thingies better?

@MTRNord For Tokio mutexes, the main alternative is a message passing design

@MTRNord (Note I don't have a problem with synchronous mutexes)

@rain this is really interesting, thank you! Hope the guide will be public because it sounds like it will be worth reading.