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
Made sure detail::condition_variable can be safely destroyed #1488
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright 2015 (c) Hartmut Kaiser | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|
||
// This test case demonstrates the issue described in #1481: | ||
// Sync primitives safe destruction | ||
|
||
#include <hpx/hpx.hpp> | ||
#include <hpx/hpx_main.hpp> | ||
#include <hpx/include/local_lcos.hpp> | ||
#include <hpx/util/lightweight_test.hpp> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test is called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uhh, right. It still relies on the behavior of the condition_variable, though. Let's change the name of the test, though. |
||
|
||
void test_safe_destruction() | ||
{ | ||
hpx::thread t; | ||
hpx::future<void> outer; | ||
|
||
{ | ||
hpx::lcos::local::promise<void> p; | ||
hpx::shared_future<void> inner = p.get_future().share(); | ||
|
||
// Delay returning from p.set_value() below to destroy the promise | ||
// before set_value returns. | ||
outer = inner.then( | ||
[](hpx::shared_future<void> &&) | ||
{ | ||
hpx::this_thread::sleep_for(boost::chrono::milliseconds(100)); | ||
}); | ||
|
||
// create a thread which will make the inner future ready | ||
t = hpx::thread([&p]() { p.set_value(); }); | ||
inner.get(); | ||
} | ||
|
||
outer.get(); | ||
t.join(); | ||
} | ||
|
||
int main() | ||
{ | ||
test_safe_destruction(); | ||
return hpx::util::report_errors(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this change mean that we have to go over all uses of
notify_one
and make sure that the result is the expected one? I believe this would lead tounlock()
being called in an already unlocked mutex.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went through all current uses of
detail::condition_variable::notify_one
and fixed its uses. Also a unlocked lock will not touch the mutex anymore (at least notboost::unique_lock
which we usually use as the scoped lock mechanism). All of this is not too satisfying, but I believe it's the best we can currently do.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went through all use cases too and they are fine in a surprising way. This is mostly because they all use nested
::scoped_lock
, which are not scoped locks butunique_lock
s. This is at least fragile.All uses of this condition variable are implementation details, so this is not a big deal. We should make a note or ticket to review this in a future, in particular once we move away from nested
scoped_locks
.