Boost logo

Boost :

Subject: Re: [boost] We need a coherent higher level parallelization story for C++ (was [thread] Is there a non-blocking future-destructor?)
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2015-10-13 13:48:59


Le 13/10/15 10:39, Mikael Olenfalk a écrit :
> On Tue, Oct 13, 2015 at 4:02 AM, Vicente J. Botet Escriba <
> vicente.botet_at_[hidden]> wrote:
>
>> Le 12/10/15 14:52, Hartmut Kaiser a écrit :
>>
>>> Sorry for cross-posting.
>>>
>>> Vicente J. Botet Escriba wrote:
>>>> I have a branch
>>>> (https://github.com/boostorg/thread/tree/feature/non_blocking_futures)
>>>> that don't blocks on any future, but this will break async.
>>>>
>>> FWIW, the design decision to let those (and only those) futures block on
>>> destruction which are returned from async was one of the really bad
>>> decisions made for C++11, however that's just my opinion (others agree,
>>> but
>>> yet others disagree).
>>
> For what it is worth, I cannot figure out how to use future<> when the
> destructor blocks as it "breaks" most of my usecases. Then again just
> giving future a detach() member would solve it for me at least.
>
> We (as a community) really need a higher level, over-arching approach which
>>> ties all of the above together! My plan is to work on a corresponding
>>> concept paper by the time of the committee meeting end of February 2016.
>>>
>> I plan to update the N4414 Executors and Schedulers Revision 5 proposal as
>> I believe that Executors must be copyable and lightweight.
>> The new proposal P0008R0 comes back to executors that are not copyable and
>> so left the responsibility of the the lifetime to the user (I'm
>> experimenting it in branch make_executors_copyable)
>
> (disclaimer: I haven't had time to play with the branch just yet)
>
> I agree that making lifetime the problem of the user is not particularly
> nice. I'd prefer to split the executors interface where only the part which
> contains submit() is copyable and let the rest be non-copyable, we have
> successfully used a similar design internally (it makes the interface which
> is sent around and copied the smallest possible interface).
>
>
What you propose is something similar to the split in [p0113r0] where
there is an execution_context and executor_type.
However using shared_ptr as copyable ensures the lifetime issue, but I
don't see the advantage in the split then. There is a problem with the
shared_ptr approach that my current implementation in
make_executors_copyable shares. The destructor of the shared state can
be called in a thread that is part of the threads of the executor. That
mean that the destructor must check if the thread to join is this thread
and then not call the join.

In [p0113r0], the executor_context must outlive the executor_type copies
that can be just references to the executor_context.

E.g

class priority_scheduler : public execution_context
{
public:
   class executor_type
   {
   public:
     executor_type(priority_scheduler& ctx, int pri) noexcept
       : context_(ctx), priority_(pri)
     {
     }

     // ...

   private:
     priority_scheduler& context_;
     int priority_;
   };

   executor_type get_executor(int pri = 0) noexcept
   {
     return executor_type(*this, pri);
   }

   // ...
};

I don't see the need for the split in [p0113r0], as passing the
executors by reference is equivalent.

So, do we want a design that force the user to ensure that the executor
(execution_context) outlive the executor sinks (executor_type?
Or, just a copyable executor?

Best,
Vicente
[p0113r0] Executors and Asynchronous Operations, Revision 2
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0113r0.html


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk