chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.73k stars 1.2k forks source link

Not able to cancel operation using awaitable operators #1345

Closed magni-mar closed 11 months ago

magni-mar commented 11 months ago

Note: Not sure if this is due to Asio bug, Azmq bug or my own ignorance.

I am using an Azmq library to read off a socket, this library uses its own type of socket (azmq::socket) which I am pretty sure is a wrapper for a boost::asio::socket. The flow of execution is the following:

auto val = co_await(azmq::async_receive(socket_, asio::buffer(buffer), asio::use_awaitable) || timer(std::chrono::seconds{1}));
template<class CompletionToken, class MutableBufferSequence>
auto async_receive(azmq::socket &socket, MutableBufferSequence const &buffers, CompletionToken &&token) -> BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(boost::system::error_code, size_t)) {
    return boost::asio::async_initiate<CompletionToken, void(boost::system::error_code, size_t)>(async_receive_initiation<MutableBufferSequence>{socket, buffers}, token);
}
template<typename MutableBufferSequence>
struct async_receive_initiation {
  azmq::socket &socket;
  MutableBufferSequence const &buffers;

  template<typename CompletionHandler>
  void operator()(CompletionHandler &&completion_handler) {
      auto executor = boost::asio::get_associated_executor(
          completion_handler, socket.get_executor());
      socket.async_receive(buffers, boost::asio::bind_executor(executor,
                                                            std::bind(std::forward<CompletionHandler>(completion_handler), std::placeholders::_1, std::placeholders::_2)));
  }
}
template<typename MessageReadHandler>
void async_receive(MessageReadHandler && handler, flags_type flags = 0) {
        using type = detail::receive_op<MessageReadHandler>;
        get_service().enqueue<type>(get_implementation(), detail::socket_service::op_type::read_op, std::forward<MessageReadHandler>(handler), flags);
}

The problem arises when the timer fires, the async_receive is not cancelled. I have read the Asio documentation but to no avail. What is the problem? Is the async_receive missing a method on it? I have tried to read up on what actually happens when the operation is cancelled but I have not found much. All help is appreciated.

magni-mar commented 11 months ago

I have written up this problem with tcp socket and have determined that the issue is contained to azmq sockets and therefore not an issue with Boost.Asio.