1

Is the following code safe?

boost::asio::io_service io_service;
auto socket(new std::unique_ptr<boost::asio::tcp::socket>(io_service);
.
.
.
boost::asio::async_read(*socket, buffer, handler);
socket.reset();

Or do I need to wait for the handler to run before I am allowed to delete the socket? Also will using socket->async_receive(...) instead make any difference

I am interested in this on both windows and linux.

doron
  • 27,972
  • 12
  • 65
  • 103
  • Doing `socket-recv()` will cause your calling thread to block until you receive message on the socket...which might never happen as well. – Arunmu Jul 05 '16 at 10:08
  • @Arunmu oops, changed recv to async_receive – doron Jul 05 '16 at 10:13
  • I dont think thats a good idea. Any reason why you want to close the socket before a read happens (may) on that socket ? You could close the socket in you read handler or set a timeout wherein you do a `cancel` on the socket on then close it. – Arunmu Jul 05 '16 at 11:48
  • @Arunmu The use case is application shutdown. – doron Jul 05 '16 at 12:36
  • Hmm..that opens up another question, do you want the socket to be active throughout the runtime and only be closed during shutdown ? Seems more like to be a job of a destructor who owns the creation of the socket. – Arunmu Jul 05 '16 at 13:12

1 Answers1

1

Resetting the pointer calls the destructor on the socket. The destructor explicit cancels any async operations, so that is fine.

There's the issue with threading, though. You cannot invoke the destructor while another member of socket is being accessed because the type is not threadsafe.

The usual shutdown patterns are to /post/ operations on the IO objects (like socket) on their respective strand, and/or to stop() the service itself and wait for the service threads to return.

Also related: Why do we need to use boost::asio::io_service::work?

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633