title: Boost::asio - how to interrupt a blocked tcp server thread?
body: <p>I'm working on a multithreaded application in which one thread acts as a tcp server which receives commands from a client.  The thread uses a Boost socket and acceptor to wait for a client to connect, receives a command from the client, passes the command to the rest of the application, then waits again.  Here's the code:</p>
  
  <pre><code>void ServerThreadFunc()
  {
      using boost::asio::ip::tcp;
      boost::asio::io_service io_service;
      tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port_no));
  
      for (;;)
      {
          //  listen for command connection
          tcp::socket socket(io_service);
          acceptor.accept(socket);
  
          //  connected; receive command
          boost::array&lt;char,256&gt; msg_buf;
          socket.receive(boost::asio::buffer(msg_buf));
  
          //  do something with received bytes here
      }
  }
  </code></pre>
  
  <p>This thread spends most of its time blocked on the call to <code>acceptor.accept()</code>.  At the moment, the thread only gets terminated when the application exits.  Unfortunately, this causes a crash after main() returns - I believe because the thread tries to access the app's logging singleton after the singleton has been destroyed.  (It was like that when I got here, honest guv.)</p>
  
  <p>How can I shut this thread down cleanly when it's time for the application to exit?  I've read that a blocking accept() call on a raw socket can be interrupted by closing the socket from another thread, but this doesn't appear to work on a Boost socket.  I've tried converting the server logic to asynchronous i/o using the <a href="http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp" rel="noreferrer">Boost asynchronous tcp echo server example</a>, but that just seems to exchange a blocking call to <code>acceptor::accept()</code> for a blocking call to <code>io_service::run()</code>, so I'm left with the same problem: a blocked call which I can't interrupt.  Any ideas?</p>