Boost logo

Boost :

From: Anthony Williams (anthony.ajw_at_[hidden])
Date: 2008-05-30 08:06:10


Johan Torp <johan.torp_at_[hidden]> writes:

> Anthony Williams-4 wrote:
>>
>>> After thinking more carefully on the problem I've realized it is
>>> implementable using condition variables. Here is a revised proposal,
>>> which -
>>> for now - excludes barriers.
>>
>> Given wait_for_any and wait_for_all (see my latest revision), I don't
>> think we need these more complex composite classes in many cases, and
>> where we do they might be better implemented specifically for the case
>> at hand.
>>
>
> I agree we do not need this complex functionality in most cases. I too want
> to find a minimal interface which we can implement and get accepted into
> boost first, then we can add rich functionality - as Gaskill's proposal - on
> top of it. I hope we can find something much simpler than what I proposed
> without exposing the "completed callback". I fear that it might be difficult
> though.
>
> I don't think your proposed interface is powerful enough to implement
> composed futures, but I might be wrong. For instance, how would you
> implement future operators with it?
>
> future<bool> operator||(future<bool> lhs, future<bool> rhs);

Using wait callbacks:

    namespace detail
    {
        template<typename R>
        class future_or
        {
            boost::shared_ptr<packaged_task<R> > task;
            shared_future<R> lhs;
            shared_future<R> rhs;
            
        public:
            future_or(boost::shared_ptr<packaged_task<R> > const& task_,
                      shared_future<R> const& lhs_,
                      shared_future<R> const& rhs_):
                task(task_),lhs(lhs_),rhs(rhs_)
            {}
            
            R operator()()
            {
                unsigned const index=wait_for_any(lhs,rhs);
                
                return index?rhs.get():lhs.get();
            }

            static void run(jss::packaged_task<int>& pt)
            {
                try
                {
                    pt();
                }
                catch(task_already_started&)
                {
                }
            }
            
        };
        
    }
    

    template<typename R>
    unique_future<R> operator||(shared_future<R> const& lhs,shared_future<R> const& rhs)
    {
        boost::shared_ptr<packaged_task<R> > task(new packaged_task<R>);
        
        *task=packaged_task<R>(detail::future_or<R>(task,lhs,rhs));

        task->set_wait_callback(detail::future_or<R>::run);
        
        return task->get_future();
    }

Alternatively, you could have future_or spawn a thread to run the task
rather than do it lazily as a wait callback.

Anthony

-- 
Anthony Williams            | Just Software Solutions Ltd
Custom Software Development | http://www.justsoftwaresolutions.co.uk
Registered in England, Company Number 5478976.
Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL

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