Need help with Condvar deadlock

I'm working on managing threads for different tasks, and want to be able to pause / resume thread execution given some user input. However, I'm running into a problem where (I think) I have a deadlock with the RwLock I'm using for mutating the HashMap.

Here is a playground example. Any help would be appreciated!

Sure, the worker thread is holding onto the RwLock read handle while waiting on the condition variable. This means that the TASKS.write() call in fake_pausing blocks. In your particular code example this loop doesn’t even need mutable access, so using for (task_id, (in_progress, cvar)) in “fixes” the deadlock. Still, I presume you might want to add some tasks while others are already running and potentially waiting on their condition variable. In this case, you’d need to add a possibility to access the (Mutex<bool>, Condvar) without holding onto the HashMap. Probably easiest to put it into an Arc.

Edit: For a code example of an Arc version see this playground where the .read().iter() “fix” is not implemented. (Which doesn’t mean you shouldn’t also add this fix as it removes the overhead of the additional .write() access.)

1 Like

Thank you!

Regarding the Arc idea, could you explain why that's necessary? I used parkling_lot::RwLock instead of std's because, from what I understand, that will eventually allow the write to happen even when the workers are constantly reading.

RwLock is pretty much like a mutex, just that the group of all readers can lock the thing inside collectively. Still, if one individual reader doesn't eventually give up their share of the collective readers lock then you have a deadlock where no new writers can lock the thing and curiously also often at a point, no new readers can join either. The latter point is precisely about what you might have read. If there's lots of "reader-traffic" so to say, they can't collectively starve the writers. AFAIK, as soon as a writer starts waiting for their turn, no new reader can join the shared readers lock anymore until the writer got their turn and released the lock again. The guarantee is that multiple readers cannot cooperate to indefinitely block all the writers, as long as any individual reader always only holds the lock for a "short" amount of time.