Subject: Re: [Boost-bugs] [Boost C++ Libraries] #10056: boost::promise runs arbitrary code while holding mutex lock
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-05-31 00:38:06
#10056: boost::promise runs arbitrary code while holding mutex lock
------------------------------------------------+----------------------
Reporter: Jonathan Wakely <jwakely.boost@â¦> | Owner: viboes
Type: Bugs | Status: assigned
Milestone: To Be Determined | Component: thread
Version: Boost 1.54.0 | Severity: Problem
Resolution: | Keywords:
------------------------------------------------+----------------------
Comment (by jwakely.boost@â¦):
call_once adds a bit of overhead, but is only a bottleneck if multiple
threads are trying to make the shared state ready at the same time, and
since all but the first are going to fail with an exception containing
promise_already_satisfied it doesn't really matter if they're blocked on
call_once.
From memory, my design is roughly:
{{{
void
state::set(function<unique_ptr<Result>()> setter)
{
unique_lock<mutex> l(m_mutex, defer_lock);
call_once(m_once, &state::do_set, this, ref(setter), ref(l));
if (!l.owns_lock())
throw_promise_already_satisfied_err();
}
void
state::do_set(function<unique_ptr<Result>()>& setter, unique_lock<mutex>&
l)
{
auto result = setter(); // run without lock held
l.lock();
m_result.swap(result); // non-blocking
}
}}}
`Result` is a wrapper for the result, containing `exception_ptr` and `R`
for a `future<R>`, or `exception_ptr` and `R*` for `future<R&>`, or just
`exception_ptr` for `future<void>`. The `setter` function creates a new
`Result` and sets its members (possibly by running a deferred function or
a packaged_task's callable) and any copy construction of `R` happens
inside that setter, before the mutex is locked.
The mutex is locked to transfer the `Result` into `m_result`, and also
locked by waiting functions checking whether `m_result != nullptr`.
I'm not sure that Boost's implementation should support my strange
scenario - I'm still not certain my testcase is valid. No other
implementations seem to support it, and maybe noone really cares if it
works, so a severe refactoring probably isn't worth it.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/10056#comment:6> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:16 UTC