@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 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.
@rain https://github.com/tokio-rs/website/pull/714 alright, I suppose I will submit it then :D
@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.