
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. ---------------------------- Proposal ---------------------------- Add class future_expression that basically is a function which depend on futures values. - A typed evaluation function (some work) is associated with each future dependency --- This evaluation can result in that the future_expressions becomes ready - A future dependency is a parent child relationship. This forms a graph where "promise-futures" are leafs. --- You can wait() on any future in the graph - When a future is completed it tells it's parents they need to re-evaluate via a future-complete callback --- The future_expression that needs re-evaluation will: --- 1. Schedule the associated evaluation to be run on the client thread on next wait or is_ready is called --- 2. Notifies it's condition in case the client thread was waiting on this particular node --- 3. Signals it's parents they too need to re-evaluate ------ This way, the notifications propagate upwards to the root future ------ Some future_expression might be scheduled for re-evaluation even though - When a future expression becomes ready it drops it's shared ownership to all depending childs --- They are no longer needed and can die --- This is done as a part of the pending evaluations on the client thread - For now this is not a concurrent object, neither are the futures formed from it --- All evaluation code can thus be single threaded --- We can change this so that the work of evaluating a future is done by the first thread waiting on it. Note: - The callback is ONLY usable by future_exprs. - No user code can be executed by promise fulfilling code - Other abstractions build on future_expressions rather than the dangerous complete-callback ---------------------------- Part of interface ---------------------------- template<class T> struct future_result { T running_result_; bool value_is_final_; optional<exception> exception_; ... }; /// A representation of a function which depends on futures. /// template <class T> class future_expression { /// Default value if no dependencies are added future_expression(T starting_value); /// Add a future alongside with an evaluation function which will be called lazily by waiting threads template<class U> void add_dependency<U> (shared_future<U> f, function<void(U future_value, future_result<T>& result_setter)> on_ready); /// Perform pending evaluations. If none sets an exception or result wait on the internal condition void wait(); /// If not ready, perform pending evaluations. If none sets an exception or result, return false bool is_ready(); }; ---------------------------- Example code ---------------------------- void set_if_true(bool b, result& result_setter) { if (b) { result_setter.running_value_ = true; result_setter.value_is_final_ = true; } } template<class T> future<bool> operator||(future<bool> lhs, future<bool> rhs) { future_expression<R> exp(false); exp.add_dependency(a1, &set_if_true); exp.add_dependency(a2, &set_if_true); return future<R>(exp); } template<class T> void running_add(T value, result& result_setter) { result_setter.running_value_ += value; } template<class T> future<T> sum(vector<future<T>> futures) { future_expression<T> exp(value_initialized<T>()); for f in futures exp.add_dependency(f, &running_add); return future<T>(exp); } ---------------------------- Conclusions ---------------------------- This mechanism would solve all the issues we've found. Most importantly it allows making composite futures while prohibiting execution of user code while fulfilling promises. Unfortunately, I feel it might be a little cumbersome to use. Also, since we need wait_for_many support it needs to get accepted alongside with the first version of the future library. I was hoping this version could be very lightweight. What do you think? Any quick thoughts? Johan -- View this message in context: http://www.nabble.com/-future--Early-draft-of-wait-for-multiple-futures-inte... Sent from the Boost - Dev mailing list archive at Nabble.com.