Silvija Ida
Silvija Ida

Reputation: 13

Customising socket/close syscalls in boost::asio

I have a library which communicates with TCP and UDP sockets using boost::asio. This library is cross-platform and delegates some operations to the application using it via callbacks. In the case of sockets, the following must occur:

  1. Library opens a socket (for an outbound connection).
  2. Application receives a callback allowing it to customise behaviour
  3. Library connects a socket and uses it
  4. Application receives a callback allowing it to do any necessary cleanup
  5. Library closes the socket

Here's how I thought I can achieve this:

class CustomizableTcpSocket {
public:
  template <typename T, typename U>
  auto async_connect(T&& endpoint, U&& handler) {
    boost::system::error_code ec;
    socket_.open(endpoint.protocol(), ec);
    native_code_.socket_did_open(socket_.native_handle());
    return socket_.async_connect(std::forward<U>(handler));
  }

  // same for async_write_some as well
  template <typename... Args>
  auto async_read_some(Args&&... args) {
    return socket_.async_read_some(std::forward<Args>(args)...);
  }

  ~CustomizableTcpSocket() {
    if (socket_.is_open()) {
      native_code_.socket_will_close(socket_.native_handle());
    }
  }

private:
  NativeCode native_code_;
  boost::asio::ip::tcp::socket socket_;
};

What I'm finding is that asio is sometimes closing the socket (at the OS level) before my destructor fires.

Is there a way I can be notified of a socket closing before asio actually does it?

Upvotes: 1

Views: 130

Answers (1)

rustyx
rustyx

Reputation: 85481

ASIO has a debugging feature called handler tracking.

You could use it to intercept socket closures which are invoked as:

  BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), "socket", &impl, impl.socket_, "close"));

Just #define BOOST_ASIO_HANDLER_OPERATION(...) to whatever function you want called and in there check that arg 5 == "close".

Here's an example of how to use handler tracking.

For reference: the actual close() operation is not straightforward. Better to leave that as it is.

Upvotes: 1

Related Questions