anderas
anderas

Reputation: 5854

(How) Can I get a callback on a boost::asio::io_service when a std::future is ready?

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

Answers (2)

Lingxi
Lingxi

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

Hilborn
Hilborn

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

Related Questions