Boost logo

Boost :

Subject: Re: [boost] Futures Review - Should packaged_task beCopyConstructible?
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2009-02-10 12:00:56


Hello, I first posted this two weeks ago, allow me to repost just in
case it went unnoticed:

Best,
Vicente
----- Original Message -----
From: "vicente.botet" <vicente.botet_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Monday, January 26, 2009 11:00 PM
Subject: Re: [boost] Futures Review - Should packaged_task beCopyConstructible?

>
> Hi,
>
> Currently when we set_wait_callback on a packaged_task, the packaged_task is given by reference to the callback function. This means that the packaged_task can not be moved.
>
> As packaged_task is not CopyConstructible this limits quite a lot its use together with set_wait_callback. We need to pass it always by reference as functions parameters and can't be returned by a function.
>
> I have tried to make a lazy_call function similar to spawn_task in the defined in N2709
>
> template<typename F>
> std::unique_future<typename std::result_of<F()>::type> spawn_task(F f)
> {
> typedef typename std::result_of<F()>::type result_type;
> std::packaged_task<result_type()> task(std::move(f));
> std::unique_future<result_type> res(task.get_future());
> std::thread(std::move(task));
> return res;
> }
>
> Here it is
>
> template<typename F>
> std::unique_future<typename std::result_of<F()>::type> lazy_call(F f)
> {
> typedef typename std::result_of<F()>::type result_type;
> std::packaged_task<result_type> task(std::move(f));
> task.set_wait_callback(invoke_lazy_task<result_type>())
> std::unique_future<result_type> res(task.get_future());
> return res;
> }
>
> but I need to return the packaged_task instead of the future because its lifetime must be longuer than the future->get() call. So I've tried to move the packaged_task which don't work either because the promise is broken
>
> template<typename F>
> std::packaged_task<typename std::result_of<F()>::type> lazy_call(F f)
> {
> typedef typename std::result_of<F()>::type result_type;
> std::packaged_task<result_type> task(std::move(f));
> task.set_wait_callback(invoke_lazy_task<result_type>())
> return task;
> }
>
> Is there a way to implement this kind of function, other than wrapping the packaged_task on a CopyConstructible class?
>
> template<typename F>
> shared_ptr<std::packaged_task<typename std::result_of<F()>::type>> lazy_call(F f)
> {
> typedef typename std::result_of<F()>::type result_type;
> shared_ptr<std::packaged_task<result_type>> task_ptr(new std::packaged_task<result_type()> (std::move(f)));
> task_ptr->set_wait_callback(invoke_lazy_task<result_type>())
> return task_ptr;
> }
>
> What is the rationale for making packaged_task movable only? Why should not be CopyConstructible?
>
> Thanks,
> Vicente
>
>
> ==========
> template <typename T>
> struct invoke_lazy_task {
> typedef void result_type;
> void operator()(packaged_task<T>& task) {
> try {
> task();
> } catch(task_already_started&) {}
> }
> };
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>


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