Graeme
Graeme

Reputation: 4592

Thread-safely closing a boost::asio::ip::tcp::socket being used synchronously

Given that the boost::asio::ip::tcp::acceptor and boost::asio::ip::tcp::socket are both marked as non-thread safe as of Boost 1.52.0, is it possible to shutdown a tcp::acceptor currently blocking on accept() from a separate thread?

I've looked at calling boost::asio::io_service::stop() and this looks possible as io_service is thread safe. Would this leave the io_service event loop running until any processing being done on the socket are complete?

I am operating synchronously as this is as simple event loop as part of a bigger program and don't want to create additional threads without good reason which I understand async will do.

Upvotes: 3

Views: 4057

Answers (3)

Galimov Albert
Galimov Albert

Reputation: 7357

If your acceptor is in async_accept, you can call ip::tcp::acceptor::cancel() to cancel any async operations on it. Note this may fire handlers in this acceptor with the boost::asio::error::operation_aborted error code.

If you're using synchronous accept, it seems impossible since I think it's not related to io_service at all.

Upvotes: 4

JSON
JSON

Reputation: 1835

I think your over thinking this a little. Use a non-blocking accept or a native accept with a timeout within a conditional loop. Add a mutex lock and it's thread safe. You can also use a native select and accept when new connection arrive. Set a timeout and a conditional loop for the select.

Upvotes: 0

Graeme
Graeme

Reputation: 4592

Having spent some time looking into this there is only 1 thread safe manner in which this can be achieved: by sending a message to the socket (on a thread not waiting on accept()) telling the thread to close the socket and the acceptor. By doing this the socket and acceptor can be wholly owned by a single thread.

As pointed out separately, io_service is only of use for asynchronous operations.

Upvotes: 4

Related Questions