Reputation: 13
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:
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
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