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:
- Library opens a socket (for an outbound connection).
- Application receives a callback allowing it to customise behaviour
- Library connects a socket and uses it
- Application receives a callback allowing it to do any necessary cleanup
- 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?