#include <qi/futuregroup.hpp>
Provides helper containers for managing qi::Future
objects lifetime.
Global Classes
class qi::ScopedFutureGroup
Functions (class qi::ScopedFutureGroup)
class Service
{
// ...
public:
void add(Data data)
{
// No Future is ever canceled even if Service is destroyed!
qi::Future<PreparedData> ft = qi::async<PreparedData>(
boost::bind(&Service::prepare, this, data));
ft.andThenR<void>(boost::bind(&Service::process, this));
}
private:
PreparedData prepare(Data data);
void process(PreparedData& data);
// ...
};
// ...
class SomeApplication
{
// ...
public:
// ...
void run(std::vector<Data> alldata)
{
Service service;
while(!alldata.empty())
{
service.add(alldata.back()); // launches tasks
service.pop_back();
}
mainLoop(); // return on exit
// We cannot wait for service's tasks to end.
} // service is destroyed here but its tasks have not been canceled and might still be running!
};
In this example, once mainLoop()
call returns, if service
‘s tasks launched in add()
didn’t finish yet, they will try to acceed to a destroyed Service object.
qi::ScopedFutureGroup
helps fix the second case. This is apropriate for our example
because we want to cancel tasks only when the application is destroyed.
qi::ScopedFuture
can register cancellable futures which will be cancelled if not already
finished when the qi::ScopedFutureGroup
is destroyed.
We can fix the example from the Rationale section by using it this way:
#include <qi/futuregroup.hpp>
class Service
{
// ...
qi::ScopedFutureGroup _runningTasks; // On destruction, cancel all registered futures still running.
public:
void add(Data data)
{
// Here we made sure to track the futures associated with this object.
_runningTasks.add(qi::async(boost::bind(&Service::prepare, this, data))
.andThenR<void>(boost::bind(&Service::process, this)));
}
// If we want to explicitely cancel all tasks running without destroying the Service object.
void cancel()
{
_runningTasks.cancelAll();
}
private:
PreparedData prepare(Data data);
void process(PreparedData& data);
// ...
};
In this case a Service
object will automatically cancel all tasks still running associated with
the futures registered using qi::ScopedFutureGroup::add
.
qi::ScopedFutureGroup
will automatically stop tracking the future.qi::Future
which have not been setup to be cancellable will
be ignored at runtime and a warning will be logged. Therefore it is possible
to use qi::ScopedFutureGroup
in generic template classes and algorithms if you
cannot know if the futures you get are cancellable or not.#include <qi/futuregroup.hpp>
noncopyable
, qi::Trackable< ScopedFutureGroup >
~ScopedFutureGroup
()add
(Future<T> future)cancelAll
()empty
() constsize
() constCancel a group of unfinished registered futures on destruction. Guarantees that the registered set of futures will be canceled whatever the reason of the destruction of the group. All public member functions are thread-safe unless specified.
qi::ScopedFutureGroup::
~ScopedFutureGroup
()¶Destructor, cancel all unfinished futures registered.
Brief:
Parameters: |
|
---|
qi::ScopedFutureGroup::
add
(Future<T> future)¶Register a future to be canceled if not finished when this object is destroyed, or if cancelAll() is called. Futures finishing before cancelation will be automatically unregistered. Non-cancelable futures will be ignored.
qi::ScopedFutureGroup::
cancelAll
()¶Cancel all registered futures and unregister them.
qi::ScopedFutureGroup::
empty
() const
¶Brief:
Returns: | True if there is no future registered, false otherwise. |
---|
qi::ScopedFutureGroup::
size
() const
¶Brief:
Returns: | Count of registered futures. |
---|