Reputation: 349
Could I close tcp::socket in different thread from the sync-reading thread? It looks like:
boost::asio::ip::tcp::socket* tcp_socket; //blocking mode
thread1:
while(true){
try{
std::vector<char> read_buffer(10);
tcp_socket->read_some( boost::asio::buffer( read_buffer ) );
}
catch(boost::system::system_error& e){
//TODO
break;
}
}
thread2:
tcp_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
tcp_socket->close();
I saw the document of tcp::socket. They say the object is thread-unsafty.But the demo code seems working well. So Is it safe? What about tcp::acceptor? Could I invoke close and accept in multithreading on same tcp::acceptor?
Upvotes: 3
Views: 2124
Reputation: 8401
The documentation states that tcp::socket
is not thread safe for shared objects.
Don't count on it seemingly working as a guarantee that it will always work.
Moreover, closing a socket from another thread, at the socket layer, is not a portable way of getting the blocking thread to unblock.
Here's what I would suggest:
Quoting the author on a similar question:
Actually...
In practice, it will probably work on the platforms asio currently supports**. However, I have deliberately specified the interface such that it is not thread safe. This is to permit implementations to store additional state in the socket object without needing explicit synchronisation.
If you want to run multiple concurrent operations on the same socket, the safe, portable way is to use the asynchronous operations.
**Unless you make the socket non-blocking.
Cheers, Chris
Upvotes: 5
Reputation: 54589
It is safe, as long as you can guarantee that no other thread is using the tcp_socket
after closing. For your example, if thread1 was still in the read-loop while thread2 was attempting to close the thread, you will have a race-condition.
You can use thread-shared variables to signal thread1 to quit the loop and use a barrier to ensure the socket is only closed after thread1 is in a safe state.
Upvotes: 2