
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Friday 23 May 2008 05:45 am, Johan Torp wrote:
Interesting! Do you use these within poet anywhere or is it for poet users only?
It's only for users at the moment, I haven't rewritten the schedulers to use it.
I think it would be good to add some functionality though. For simplicity, let's only talk about the select case. This is what I propose:
How about an additional future_select overload which accepts two boost::shared_container_iterators as arguments, and returns a future<shared_container_iterator>? The returned iterator would point at the future which is ready or has an exception. Then the caller could use the returned iterator to erase the element from the container before calling future_select again. The shared_container_iterator would insure the input container of futures doesn't die before the return future becomes ready.
1. Clients will probably be interested in which of the child futures fired. The interface should support this.
2. Upon notification from a child, I'd want to be able to check a condition and then either a - become ready b - prune the "consumed" child future and go back to sleep 2.1 This condition checking should probably be done by the first thread which is waiting for the future - it belongs to the future-listening threads, not the promise-fulfilling one. If nobody is waiting for the future we should save this evalution and let it be performed lazily as soon as someone queries the future or waits for it. 2.2 This evaluation is not just a predicate which can make the future ready. It can also be actual calculations. These would be performed from within future::wait(), get() and is_ready(). 2.3 We probably need to supply a default value if all children have been consumed
Having a future execute a callback at the end of a wait completing seems only marginally useful to me. I'm not sure it's worth the complication.
3. We probably want to support composite futures from different types. If we want to support 1 or 2 we want to get access to the typed value of the ready future. In practice, this probably means the evaluation function should be added at the same time as the child future to ensure type safety. See the interface example below.
A simplified example of what an interface which supports 1, 2 and 3 might look like is:
template<class ReturnType, class Arg1Type, class Arg2Type> future<ReturnType> future_select(future<Arg1Type> f1, function<optional<ReturnType>(Arg1Type)> e1, future<Arg2Type> f2, function<optional<ReturnType>(Arg2Type)> e2, ReturnType default_value);
I'm not entirely satisfied with this though.
Oh, now its clear to me why you were using the name future_switch.
In the end, I want users to be able to easily "lift" ordinary functions to futures: int foo_func(int, double, bool) => future<int> foo_func(future<int>, future<double>, future<bool>)
That's exactly what poet::active_function does, or did you have something different in mind?
I have also been thinking about we could move part of this composed waiting in to a conditon_variable_node class to separate concerns. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFINsy+5vihyNWuA4URAj/aAKC5FhgCf3V7oqvAqb3JfsFUPDEbYwCgrJ+P 7J6qL6wPx9y771rTX1e5Q9w= =ebvj -----END PGP SIGNATURE-----