Boost logo

Boost Users :

Subject: [Boost-users] ASIO: custom service which works with spawn/yield
From: Cristian Morales Vega (cristian_at_[hidden])
Date: 2018-07-25 14:25:41


Hi,

I have implemented a custom service using Boost 1.67 which works
mostly OK, but I have noticed it always returns success when using
spawn/yield.

The following simplified sample shows the problem:

------------------------------------------------
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/beast/core/bind_handler.hpp>
#include <iostream>

class Service : public boost::asio::io_context::service {
public:
  static boost::asio::io_context::id id;

  typedef int implementation_type;

  Service(boost::asio::io_context &io_context)
      : boost::asio::io_context::service(io_context) {}

  void construct(implementation_type &) {}

  void destroy(implementation_type &) {}
};

boost::asio::io_context::id Service::id;

template <typename Service>
class BasicObject : protected boost::asio::basic_io_object<Service> {
public:
  explicit BasicObject(boost::asio::io_context &io_context)
      : boost::asio::basic_io_object<Service>(io_context) {}

  template <typename ConnectHandler>
  auto async_method(ConnectHandler &&handler) {
    BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) typeCheck;

    boost::asio::async_completion<ConnectHandler,
                                  void(const boost::system::error_code &)>
        init(handler);

    boost::system::error_code ec = boost::asio::error::already_started;
    boost::asio::post(
        boost::beast::bind_handler(std::move(init.completion_handler),
std::move(ec)));

    return init.result.get();
  }
};

int main() {
  boost::asio::io_context ioContext;

  BasicObject<Service> myObject(ioContext);

#if 1
  boost::asio::spawn(ioContext, [&](boost::asio::yield_context yield) {
    boost::system::error_code ec;

    myObject.async_method(yield[ec]);
    std::clog << ec << std::endl;
  });
#else
  myObject.async_method([](const boost::system::error_code &ec) {
    std::clog << ec << std::endl;
  });
#endif

  ioContext.run();

  return 0;
}
------------------------------------------------

The version not using spawn prints "system:114", the one using spawn
prints "system:0". What am I doing wrong?

Thanks.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net