3
votes

I am facing the following issue. I am trying to use a third party library with boost Asio and I need to inject some of the socket descriptors used by the library in io_service event loop.

The approach I use is creating a boost::asio::ip::tcp::socket passing the native handler my library provides.

Problem is that library would just communicate it is not interested in a particular socket notifications (which means that library may close the socket or reuse it at a later point). In any case, I would like to do a clean up of boost sockets and destroy them, but without closing the native handler (i.e. file descriptor).

In short, is there any way of destroying a boost::asio::ip::tcp::socket without closing the underlying handler? I am aware of using posix::stream_descriptor instead, but I would like my solution to be portable.

3
Did you try to assign a dumb socket, even if it fails may be previous will be no more available...Jean Davy
@JeanDavy socket.assign(protocol, native) has a pre-condition that socket is not open (see the SocketService). If this precondition is not met, then the state of socket remains unchanged.Tanner Sansbury

3 Answers

2
votes

No. There is no way to destroy ip::tcp::socket without closing the native handler. This cannot be portable implemented, and therefore Asio does not support it. In particular, prior to Windows 8.1, once a socket is associated with an I/O completion port, the socket can only be disassociated by closing it1. See this related github issue where Chris Kohlhoff responds to this feature request:

This is not supported because it cannot be portably implemented. Specifically, on Windows a socket is associated to an I/O completion port and cannot be disassociated.

If you are only targeting POSIX-based systems then perhaps you can stick the descriptor into a posix::stream_descriptor instead? This class does provide a release() member function.


1. Windows 8.1 enabled removing the completion port association via FileReplaceCompletionInformation without closing the socket.

0
votes

but I would like my solution to be portable

The moment you touch the native handle, the program is no longer portable.

However, once you've come to terms with that, you can call dup() [unix] or DuplicateHandle() [windows] on the native handle.

0
votes

You can try to swtich to posix::stream_descriptor and use its release method.