title: Boost asio - stopping io_service
body: <p>I'm using boost::asio to do some very basic UDP packet collection. The io_service object is instantiated in a worker thread, and io_service.run() is called from inside that thread. My problem is getting io_service.run() to return when I am done collecting packets.</p>
  <p>I'm not clear on what methods of io_service can be called from other threads when it comes time to stop my worker thread. I have a reference to the io_service object, and from a different thread I make this call:</p>
  <pre><code>ios.dispatch( boost::bind( &amp;udp_server::handle_kill, this ) );
  </code></pre>
  <p>In my udp_server class, the handler for that function cancels the pending work from a single boost::asio::ip::udp::socket and a single boost::asio::deadline_timer object. Both have pending async work to do. At that point I call ios.stop():</p>
  <pre><code>void udp_server::handle_kill()
  {
      m_socket.cancel();
      m_timer.cancel();
      m_ios.stop();
  }
  </code></pre>
  <p>With no work pending, I expect at this point that my call to ios.run() should return - but this does not happen.</p>
  <p>So why does it not return? The most likely explanation to me is that I shouldn't be calling io_service::dispatch() from another thread. But the dispatch() method kind of seems like it was built to do just that - dispatch a function call in the thread that io_service::run() is working in. And it seems to do just that.</p>
  <p>So this leaves me with a few related questions:</p>
  <ol>
  <li>Am I using io_service::dispatch() correctly?</li>
  <li>If all tasks are canceled, is there any reason that io_service::run() should not return?</li>
  <li>socket::upd::cancel() doesn't seem to be the right way to close a socket and abort all work. What is the right way?</li>
  </ol>
  <p>asio is behaving pretty well for me, but I need to get a better understanding of this bit of architecture.</p>
  <h3>More data</h3>
  <p>socket::udp::cancel() is apparently an unsupported operation on an open socket under Win32 - so this operation fails by throwing an exception - which does in fact cause an exit from io_service::run(), but definitely not the desired exit.</p>
  <p>socket::udp::close() doesn't seem to cancel the pending async_receive_from() task, so calling it instead of socket::udp::cancel() seems to leave the thread somewhere inside io_service::run().</p>