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@wanadoo.fr> 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