Reputation: 5854
Suppose I have a library that allows to make asynchronous requests and returns a std::future
to query the (state of the) result. I want to integrate that library with a boost::asio::io_service
so that a callback is called in the io_service
loop as soon as the future is ready. Is there any way to achieve that without changing the library or regularly polling the future in the io loop?
Note: there are several questions that deal with the reverse problem, i.e. getting a std::future
that is ready when some operation on the io_service
completes (e.g. Program to read asynchronously in boost asio with C++11 future). I couldn't find a way of achieving the exact opposite, i.e. getting a callback executed on the io_service
when the future
is ready.
Upvotes: 2
Views: 1067
Reputation: 14977
How about spawning a daemon thread to do the job, like the following:
#include <future>
#include <memory>
#include <thread>
#include <utility>
#include <boost/asio.hpp>
template <class Callback, class T>
void post_when_ready(boost::asio::io_service& iosvc,
std::shared_ptr<std::future<T>> ptr,
Callback callback) {
std::thread{
[=, &iosvc] {
ptr->wait();
// ...
iosvc.post(std::move(callback));
}
}.detach();
}
Upvotes: 1
Reputation: 754
By using then
you can specify that something is to be executed when the future is ready:
future<T> my_future = lib::get_some_future();
my_future.then([] (future<T> f) {
do_something_with_io_service(f.get())
}); // .then returns a new future (future<void> in this case) that allows chaining
Note however that std::future
as of C++11 is missing a then
member function. You could instead use boost::future
or implement it yourself.
Upvotes: 2