Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hpx::lcos::condition_variable could be suspect to deadlocks #3068

Closed
sithhell opened this issue Dec 11, 2017 · 3 comments
Closed

hpx::lcos::condition_variable could be suspect to deadlocks #3068

sithhell opened this issue Dec 11, 2017 · 3 comments

Comments

@sithhell
Copy link
Member

The current code for hpx::lcos::condition_variable (and the _any variant) might lead to deadlocks.
The deadlock situation might, for example, be encountered, when concurrently calling wait.
The problem is, that the outer lock (provided from the caller) is being tried to be acquired unconditionally with the inner lock (protecting the lcos::detail::condition_variable) is being held.

@hkaiser
Copy link
Member

hkaiser commented Dec 11, 2017

I'd assume you're talking about this code: https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/lcos/local/condition_variable.hpp#L50-L65

Here, the outer lock is re-acquired in the destructor of the util::unlock_guard<> while the inner lock is still being held (and for a good reason, btw). I'm not sure what you mean by 'unconditionally' in

the outer lock (provided from the caller) is being tried to be acquired unconditionally

What condition should have been applied to that re-acquire operation?

@sithhell
Copy link
Member Author

Yes, I am talking about this code. The outer lock being re-acquired while the inner lock is being held is exactly what will lead to a deadlock:

T1              | T2
================| ================
outer.lock();   | ...
inner.lock();   | ...
outer.unlock(); | ...
inner.unlock(); | outer.lock();
inner.lock()    | inner.lock();
// Assume T1 acquired inner.lock(). T2 still holds outer, once T1 tries to acuire outer.lock, we get into a deadlock situation.
outer.lock();   | ...
inner.unlock(); | ...

With "uncoditionally", I meant that we don't consider that another lock might be held when trying to acquire the other.

@brjsp
Copy link
Contributor

brjsp commented Jan 6, 2018

This is a similiar issue to the one discussed in this article: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html (kindly provided by @K-ballo on IRC)

brjsp added a commit to brjsp/hpx that referenced this issue Jan 14, 2018
brjsp added a commit to brjsp/hpx that referenced this issue Jan 14, 2018
brjsp added a commit to brjsp/hpx that referenced this issue Jan 14, 2018
msimberg added a commit that referenced this issue Jan 16, 2018
Fix #3068 (condition_variable deadlock)
sithhell pushed a commit that referenced this issue Jan 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants