Interrupt interrupt :: asio synchronous read?

I am using asio synchronous sockets to read data over TCP from a background thread. It is encapsulated in the server class.

However, I want the thread to exit when the destructor of this class is called. The problem is that the call to any of the read functions is blocked, so the thread cannot be easily terminated. In Win32, there is an API for this: WaitForMultipleObjects , which will do exactly what I want.

How to achieve this effect with boost?

+6
source share
5 answers

In our application, we set the termination condition, and then use self-connection with the port that is listening to the stream, so it wakes up, notices the termination condition and exits.

You can also check the implementation of boost - if they do only normal reading on the socket (i.e. they do not use WaitForMultipleObjects inside themselves), then you can probably conclude that there is nothing to simply and cleanly unlock the thread. If they are waiting at several sites (or at the termination port), you can dig around to find out if the ability to wake up the blocking stream from the outside is available.

Finally, you can kill the thread, but you will need to go beyond boost to do this, and understand the consequences, such as a freeze or resource leak. If you conclude, this may not bother, depending on what else this thread is doing.

+2
source

I did not find an easy way to do this. Presumably, there are ways to cancel winOC IOCP, but it does not work very well on Windows XP. MS fixed it for Windows Vista and 7. The recommended approach for canceling asio async_read or async_write is to close the socket.

  • [destructor] notice that we want to hide
  • [destructor] close socket
  • [destructor] wait for handlers to complete

  • [completion], if the failure, and we just failed because the socket is closed, inform the destructor that the completion handlers are completed.

  • [completion] return immediately.

Be careful if you decide to implement this. Closing the nest is fairly straightforward. "Wait for handlers to complete," however, is huge unsatisfactory. There are several subtle angular cases and race conditions that can occur when the server stream and its destructor interact.

It was subtle enough that we create a trailing shell (similar to io_service::strand just to handle the synchronous cancellation of all pending callbacks.

+2
source

The best way is to create socketpair() (no matter what is in boost::asio parlance), add the end of the reader to the event loop, and then close the end of the record. You will be immediately woken up with an eof event on this socket.

Then the stream must voluntarily close itself.

The stream creator must have the following in its destructor:

 ~object() { shutdown_queue.shutdown(); // ask thread to shut down thread.join(); // wait until it does } 
+1
source
 boost::system::error_code _error_code; client_socket_->shutdown(client_socket_->shutdown_both, _error_code); 

The code above will help me read the synchronization right away.

0
source

Use socket.cancel (); to complete all current asynchronous operations that are blocked on the socket. Perhaps in a loop client sockets may be killed. I never had to close the server this way, but you can use shared_from_this () and run cancel () / close () in a loop, similar to the boost chat async_writes example for the entire client.

-one
source

All Articles