vicente.botet | 20 Jan 19:12
Picon

Re: Futures Review - wait_for_any complexity


----- Original Message ----- 
From: "Anthony Williams" <anthony.ajw <at> gmail.com>
To: <boost <at> lists.boost.org>
Sent: Tuesday, January 20, 2009 3:01 PM
Subject: Re: [boost] Futures Review - wait_for_any complexity

> 
> "vicente.botet" <vicente.botet <at> wanadoo.fr> writes:
> 

>> What we need is a synchonization structure that returns a user
>> specific data (in this case the index). So we can replace by
>>
>>     unsigned wait()
>>     {
>>         all_futures_lock lk(futures);
>>         return cv_with_value.wait(lk);
>>     }
> 
> I'm not sure. I think we're better off with a simple
> mutex/value/cond-var triplet in the waiter. We then don't need the
> "all_futures_lock".
> 
>    unsigned wait()
>    {
>        boost::unique_lock<boost::mutex> lk(mut);
>        while(ready_future_index<0)
>        {
>            cv.wait(lk);
>        }
>        return ready_future_index;
>    }

Great.

>> We need to pass to the register_external_waiter the specific data,
>> in this case the index
> 
> and the mutex => better off as a struct of some kind.
> 
> struct ready_future_value
> {
>    boost::mutex mut;
>    int ready_future_index;
>    boost::condition_variable cv;
> 
>    void notify_ready(unsigned index)
>    {
>        boost::lock_guard<boost::mutex> lk(mut);
>        if(ready_future_index<0)
>        {
>            ready_future_index=index;
>            cv.notify_all();
>        }
>    }
> } ready_value;

Yes you are right, the mutex is also needed. It was supposed to be encapsulated on my proposal.

>>     template<typename F>
>>     void add(F& f)
>>     {
>>         if(f.future)
>>         {
>>             futures.push_back(registered_waiter(f.future,
>>//             f.future->register_external_waiter(cv,future_count,mut),future_count));
> 
>            f.future->register_external_waiter(&ready_value,future_count),future_count));
> 
>>         }
>>         ++future_count;
>>     }
>>
>>
>> So the list of waiters is now 
>>     
>>//     typedef std::list<std::pair<condition_variable_any_with_value<unsigned>*, 
> 
>    typedef std::list<std::pair<ready_future_value*,
> 
>>                                 unsigned> 
>>                             > waiter_list;
>>     waiter_list::iterator register_external_waiter(
>>//                 condition_variable_any_with_value<unsigned>& cv_with_value, 
> 
>                ready_future_value& ready_value, 
> 
>>                 unsigned indx)
>>     {
>>         boost::unique_lock<boost::mutex> lock(mutex);
>>         do_callback(lock);
>>         return external_waiters.insert(external_waiters.end(),std::make_pair(&cv, indx));
>>     }
>>
>> The notification to the waiters will no use the new notify_all
>> interface passing as parameter the index of the future relative to
>> the condition_variable.
>>
>>     void mark_finished_internal()
>>     {
>>         done=true;
>>         waiters.notify_all();
>>         for(waiter_list::const_iterator it=external_waiters.begin(),
>>                 end=external_waiters.end();it!=end;++it)
>>         {
> 
>             (it->first)->notify_ready(it->second);
> 
>>         }
>>     }
> 
> It turns out that my ready_future_value struct isn't too far from your
> cv_with_value, so I like the idea, but not the name. (I don't like
> ready_future_value either for that matter).

Yes, it seems to be the same. I have no better proposal for the name now.

Hoping this will improve the performances of wait_for_any,
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Gmane