Do boost asio sockets have proper RAII cleanup
Asked Answered
V

1

7

I tried looking through source but I cant navigate that much of a template code. Basically: this is what documentation says (for close()):

Remarks    
For portable behaviour with respect to graceful 
closure  of a connected socket, call shutdown() before closing the socket.

I can do that manually, but if possible it would be nice to rely on RAII.

So if I have socket going out of scope do I need to call shutdown() and close() on it, or it will be done automatically?

Vain answered 11/2, 2014 at 19:0 Comment(6)
Why don't you just wrap the socket in a class that calls close/shutdown in the dtor?Console
A simple wrapper (similar as the usual lock guard implementations etc. pp.) would do? From your cite it seems for me they don't do this automatically on destruction of the socket.Kavanagh
@Luther Same idea at same time ;), looks like being a solution ...Kavanagh
looks like socket_holder does this, but I did not manage to find docs for it, comments in source say : namespace boost { namespace asio { namespace detail { // Implement the resource acquisition is initialisation idiom for sockets. class socket_holder : private noncopyable { public: // Construct as an uninitialised socket. socket_holder() : socket_(invalid_socket)Vain
and in dtor: ~socket_holder() { if (socket_ != invalid_socket) { boost::system::error_code ec; socket_ops::state_type state = 0; socket_ops::close(socket_, state, true, ec); } }Vain
Is this not Boost's equivalent to shutdown? (See man 2 shutdown) It gracefully closes, say, a TCP connection and causes the other side to get an EOF. (As opposed to a "Connection reset by peer.") close will release the socket regardless, and the resources will get freed, but one will transmit a clean close on the network.Wilterdink
W
4

One can rely on the socket performing proper cleanup with RAII.

When an IO object, such as socket, is destroyed, its destructor will invoke destroy() on the IO object's service, passing in an instance of the implementation_type on which the IO object's service will operate. The SocketService requirements state that destroy() will implicitly cancel asynchronous operations as-if by calling the close() on the service, which has a post condition that is_open() returns false. Furthermore, the service's close() will cause outstanding asynchronous operations to complete as soon as possible. Handlers for cancelled operations will be passed the error code boost::asio::error::operation_aborted, and scheduled for deferred invocation within the io_service. These handlers are removed from the io_service if they are either invoked from a thread processing the event loop or the io_service is destroyed.

Wakerly answered 12/2, 2014 at 0:35 Comment(3)
i will need 2 hours to understand the A, but seems legit... :)Vain
so that means if two sockets share io_service one exiting out of scope will affect other?Vain
@Vain No. The the IO object's io_service, returned from get_io_service(), is different from the IO object's service, returned from get_service(). While sockets may both use the same io_service, each socket will have its own SocketService.Wakerly

© 2022 - 2024 — McMap. All rights reserved.