Boost logo

Boost :

Subject: Re: [boost] Futures Review - Should packaged_task beCopyConstructible?
From: Anthony Williams (anthony.ajw_at_[hidden])
Date: 2009-02-10 12:28:34


"vicente.botet" <vicente.botet_at_[hidden]> writes:

>>
>> 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;
>> }

Why does this not work? Is it that the callback is broken (it gets
passed the wrong task?) If so, that's the part that needs fixing, rather
than the copyability of packaged_task.
 
>> What is the rationale for making packaged_task movable only? Why
>> should not be CopyConstructible?

If packaged_task was copyable, people would copy it and expect the copy
to be associated with the futures they obtained from the original. Not
necessarily deliberately, but by mistake (e.g. copying into a vector
rather than moving). This is not the case.

Anthony

-- 
Author of C++ Concurrency in Action | http://www.manning.com/williams
just::thread C++0x thread library   | http://www.stdthread.co.uk
Just Software Solutions Ltd         | http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

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