Boost logo

Boost Users :

Subject: Re: [Boost-users] [thread] await hangs when using boost::promise/future
From: Lee Clagett (forum_at_[hidden])
Date: 2015-01-18 01:36:23


On Sun, Jan 18, 2015 at 1:14 AM, Lee Clagett <forum_at_[hidden]> wrote:

>
> On Sat, Jan 17, 2015 at 1:55 PM, Vicente J. Botet Escriba <
> vicente.botet_at_[hidden]> wrote:
>
>> Le 17/01/15 16:36, Vicente J. Botet Escriba a écrit :
>>
>> Le 17/01/15 15:36, Lee Clagett a écrit :
>> The continuation then tries to acquire the mutex (has_exception), and
>> blocks waiting for the set_value() to clear.
>>
>> The continuation is executed in another thread and only when it is
>> ready (either there is a set_value or a set_exception). So the continuation
>> shouldn't block.
>>
>> set_value() is in turn waiting for the continuation thread to join
>> because nothing else has a handle to the thread.
>>
>> I don't understand how did you got this conclusion. Please could you
>> clarify? I can understand that the as the blocking is on the shared future,
>> the promise destructor will block in this case.
>>
>> This line here [
> https://github.com/boostorg/thread/blob/master/include/boost/thread/future.hpp#L189
> ]. this_continuation_ptr is the last thing that references the continuation
> thread, so it tries to join it during destruction, while the mutex is held
> up the call stack. If the continuation thread calls a function on the
> future it receives, it then must wait for the same mutex which will never
> be released.
>
>>
>> The best way to get around this is to _not_ ignore the returned future
>> from the .then call. I also have patch that fixes the second bug, but
>> fixing the first bug will require enough changes that will likely result in
>> an obsolete patch.
>>
>>
>> Is the patch for Boost.Thread?
>>
>> Thanks for your comments. I will try to fix this the blocking issue asap
>> but I suspect that this couldn't go into the next Boost version :(
>>
>> I have a patch here [
> https://github.com/vtnerd/thread/compare/boostorg:develop...ContinuationFix
> ] that addresses the deadlock issue, and should allow the code by the OP to
> work exactly as desired. However, the patch does not work as the docs
> indicate. Instead of blocking on the destructor of the continuation future,
> it will block in the destructor of the original future, OR the setter of
> the original promise (which could be its destructor in broken_promise
> case), whichever occurs last. Fixing the .then() blocking issue is a little
> tricky because the destructor of the continuation future could need to wait
> for a thread that won't be launched until a value is set in the original
> promise.
>
> Sorry I think I misspoke slightly here. In the patch I have listed, the
thread join will occur when the shared_continuation_state is destructed.
This is owned by the shared_state of the original promise/future and the
continuation future, which is even more confusing than I described. So in
most cases it will block in the destructor of the continuation future, or a
setter in the original promise. Hopefully I got it right this time.

Lee



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net