Boost logo

Boost :

From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2007-03-14 12:47:09


On 3/14/07, Hartmut Kaiser <hartmut.kaiser_at_[hidden]> wrote:
> [about combining mutexes]
> But as soon as you start combining || and && this isn't always possible
> anymore.
> Additional optimization can be done, if all futures in a operator|| sequence
> return the same type, in which case you don't need to use a variant.
>

Instead of going with generalized future composition, I've tried the route of
'wait_all(<future-list>) ' and 'wait_any(<future-tuple>)'

Sure, it is less flexible than overloading || and && and permitting
complex expressions, but it is easy to implement, its behavior as a
blocking point is immediate and most importantly it is simple to
understand. If you really need to wait for multiple futures with
complex patterns, simply use a full blown reactor (i.e. asio).

> > Should there be a seperate future_group concept to disambiguate?
>
> What do you mean by that?
>
> > Composition overloading with || or && gets very hairy or
> > impossible if the current proposal to have a future
> > implicitly convertable to it's value, with blocking, goes
> > through. Maybe Peter has thoughts on this.
>
> I personally don't like the idea of having the future convert implicitely to
> its value type at all. I'm not sure if this can be implemented completely
> fail proof without ruunning in surprising behavior.
>

I agree. What about an optional<T> like interface for future<T>?

you can do:

  future<some_type1> a = async_op1(...);
  some_type1 xa = *a; //may block if not yet ready

or, as a more convoluted example:

  future<some_type1> a = async_op1(...);
  future<some_type2> b = async_op2(...);
  future<void> timeout = post_timer(timeout);

 while(true){
    wait_any(a, b,c)
    if(a) {
       some_type1 xa = *a; // guaranteed not to block
       // do something with xa
   }
   if(b) {
       some_type2 xb = *b; // guaranteed not to block
      // do something with xb
   }
   if((a && b) || timeout) { //no boolean operator overloading here,
just plain builtins
      a.cancel(); //no-op if already completed.
      b.cancel(); //ditto
     break;
   }
}

> > I like the tuples/variant idea of composition, but how do you
> > handle exceptions?
>

In this case wait_any could report a failed future as ready. operator*
would throw the forwarded exception. Not sure about that though. The
futures I had implemented didn't support exception forwarding.

gpd


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