|
Boost : |
From: Johan Torp (johan.torp_at_[hidden])
Date: 2008-05-16 06:47:04
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-interface-tp17242880p17272047.html Sent from the Boost - Dev mailing list archive at Nabble.com.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk