Subject: Re: [boost] [thread] Do we can a non backward compatible version with non-blocking futures?
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2015-05-27 01:57:48


Le 26/05/15 23:43, Lee Clagett a écrit :
> On Sun, May 24, 2015 at 7:35 AM, Vicente J. Botet Escriba <
> vicente.botet_at_[hidden]> wrote:
>
>> Le 23/05/15 19:05, Lee Clagett a écrit :
>>
>>> On Thu, May 21, 2015 at 5:13 PM, Vicente J. Botet Escriba <
>>> vicente.botet_at_[hidden]> wrote:
>>>
>>> Le 21/05/15 17:11, Lee Clagett a écrit :
>>>> A non-blocking future::then() is convenient for cases like the one
>>>>> Vicente
>>>>> described, but can the executor framework simulate the same behavior?
>>>>>
>>>>> Please , could you elaborate?
>>> boost::async and boost::future::then seem error prone due to ownership of
>>> the execution handle.
>>>
>> Are talking here of blocking or non-blocking futures?
>>
> I was referring to non-blocking futures.
>
>
>> If the destructor of the boost::future automatically
>>> releases ownership, the execution handle cannot be managed.
>>>
>> Why?
>>
> It was incorrect of me to say that the execution handle cannot be managed
> (see below). I thought the separate executor argument to boost::async could
> make it more obvious that the executor object would control the lifetime of
> the execution thread, and that it could prevent possible data races. I
> doubt it will make data races to stack references easier to identify, but
> it should help prevent threads after main, since the executor object could
> force all execution threads to stop on its destruction instead. It wasn't
> obvious previously, but I was wondering whether the detach on future
> destruction should only be enabled when boost::async takes an executor
> overload.
>
>
>> It should
>>> prevent threads after main, which never seem like a good idea.
>>>
>> Sorry, I don't understand, it should prevent what?
>>
> Static destruction could be complicated if there were multiple execution
> threads after main. That was another issue brought up about not blocking on
> destruction for the std async/future versions.
So, you are saying that async() should return a blocking future if there
is no executor parameters, and a non-blocking when the executor is
given, isn't it?
>> Unfortunately, if client code throws before a boost::future::get() then
>>> stack references can still be invalidated with the executor (see my prior
>>> post) - but there are a number of ways to achieve this incorrect behavior
>>> anyway.
>>>
>>> If boost::future::~future detaches the execution handle, its still
>>> possible
>>> to create an RAII wrapper that blocks if that behavior is desired. I don't
>>> think the opposite is possible, so the change is more flexible.
>>>
>>>
>>> Could you tell us more?
>>
> Inspired by ThreadRAII:
>
> template<typename T>
> class FutureRAII {
> public:
> FutureRAII(boost::future<T>&& future)
> : future_(std::move(future)) {
> }
>
> ~FutureRAII() {
> try {
> if (future_.valid()) {
> future_.wait();
> }
> } catch (...) {
> }
> }
>
> boost::future<T>& future() { return future_; }
>
> private:
> boost::future<T> future_;
> };
>
> The usual complications of calling a function after a move can appear if
> future_ was the source of a move through the accessor.
>
>
Ok, I understand what you meant. Call it blocking_future. This class has
its own merit, but it could have also more future like functions.

Thanks for your comments,
Vicente