Boost::Asio - blocking read on socket does not disconnect when socket closed from other thread

Hi Folks, Boost version is 1.36, OS is linux rhel-4. I have an application with two threads. The secondary thread is a worker thread that manages a boost::asio tcp/ip socket. The worker thread performs blocking reads as per: try { boost::system::error_code error; boost::asio::read(mysocket, boost::asio::buffer(inputbuffer, size_to_read), boost::asio::transfer_all(), error); if(error) { throw boost::system::system_error(error); } } catch(boost::system::system_error se){ // log error here return false; } In the main application thread, in response to the user choosing to close the connection, I do: mysocket.cancel(); mysocket.close(); I would expect the worker thread to return from the blocking boost::asio::read call, with an error. This occurs on windows, but does not happen on the linux build of my app - it never returns from the above call. Why does the second thread never return? What am I doing wrong? I have considered: - implementing a timeout - but I don't want to move to async sockets. - It seems SO_RCVTIMEO, is wrapped by boost::asio::read, so no hope there. - I could kill the thread but that means it isn't cleaned up properly, so that is no good. What am I doing wrong? cheers Nick Aschberger

I would expect the worker thread to return from the blocking boost::asio::read call, with an error. This occurs on windows, but does not happen on the linux build of my app - it never returns from the above call.
Why does the second thread never return? What am I doing wrong?
Socket object is not threadsafe -- it's not safe to access it from multiple threads.

I was under the impression that it was threadsafe.
Well, the opposite is stated explicitly: http://www.boost.org/doc/libs/1_41_0/doc/html/boost_asio/reference/ip__tcp/s... (end of the page).
The only other option I have then is to allow the socket read to time out. Why is it that boost::asio::read does not timeout with "SO_RCVTIMEO" or similar, as per normal posix sockets?
IIUC, SO_RCVTIMEO is not really portable. Even if it's implemented on your platform, it probably leaves the socket in an undefined and unusable state (eg., this's stated explicitly for Winsock2). You can access the low-level socket and set whatever option you want, but note that even if SO_RCVTIMEO is supported on your platform, it affects recv() function *only*, while asio::read() probably doesn't use this function at all.
Example code I have seen for timeouts seems to be a lot more complicated than what would be done in posix, ie: http://bicosyes.com/boostasio-synchronous-read-with-timeout/
Surely there is a simpler way?
IMHO, this is the way to go. ASIO is about asynchronous i/o, and this approach is especially useful if you need reliable timeouts and cancellations.
participants (2)
-
Igor R
-
Nick Aschberger