title: boost::asio multithreaded asynchronous accept with blocking read/write server
body: <p>My idea was to create X threads, run it using KeepRunning method which has endless loop calling _io_service.run() and send tasks to _io_service when received a new connection using _io_service.poll() in async_accept handler. </p>
  
  <p>I run the server with a code like this:</p>
  
  <pre><code>    oh::msg::OHServer s("0.0.0.0", "9999", 200);
      ConsoleStopServer = boost::bind(&amp;oh::msg::OHServer::Stop, &amp;s);
      SetConsoleCtrlHandler(bConsoleHandler, TRUE);
      s.Run();
  </code></pre>
  
  <p>but when I receive one connection, then serve it in Post() method using blocking read/writes in MsgWorker class, then all the threads are being closed. </p>
  
  <p>I have code like below (it's some mix from http server3 asio example and mine):</p>
  
  <pre><code>OHServer::OHServer(const std::string&amp; sAddress, const std::string&amp; sPort, std::size_t tps)
  : _nThreadPoolSize(tps), _acceptor(_io_service), _sockClient(new boost::asio::ip::tcp::socket(_io_service))
  {
      // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
      boost::asio::ip::tcp::resolver resolver(_io_service);
      boost::asio::ip::tcp::resolver::query query(sAddress, sPort);
      boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
      _acceptor.open(endpoint.protocol());
      _acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
      _acceptor.bind(endpoint);
      _acceptor.listen();
  
      _acceptor.async_accept(
              *_sockClient,
              boost::bind(
                      &amp;OHServer::AcceptConnection,
                      this,
                      boost::asio::placeholders::error
              )
      );
  }
  
  
  void OHServer::KeepRunning()
  {
      global_stream_lock.lock();
      std::cout &lt;&lt; "[" &lt;&lt; boost::this_thread::get_id()
              &lt;&lt; "] Thread Start" &lt;&lt; std::endl;
      global_stream_lock.unlock();
  
      while( true )
      {
              try
              {
                      boost::system::error_code ec;
                      _io_service.run( ec );
                      if( ec )
                      {
                              global_stream_lock.lock();
                              std::cout &lt;&lt; "[" &lt;&lt; boost::this_thread::get_id()
                                      &lt;&lt; "] Error: " &lt;&lt; ec &lt;&lt; std::endl;
                              global_stream_lock.unlock();
                      }
                      break;
              }
              catch( std::exception &amp; ex )
              {
                      global_stream_lock.lock();
                      std::cout &lt;&lt; "[" &lt;&lt; boost::this_thread::get_id()
                              &lt;&lt; "] Exception: " &lt;&lt; ex.what() &lt;&lt; std::endl;
                      global_stream_lock.unlock();
              }
      }
  
      global_stream_lock.lock();
      std::cout &lt;&lt; "[" &lt;&lt; boost::this_thread::get_id()
              &lt;&lt; "] Thread Finish" &lt;&lt; std::endl;
      global_stream_lock.unlock();
  }
  
  void OHServer::Run()
  {
      // Create a pool of threads to run all of the io_services.
  
      for (std::size_t i = 0; i &lt; _nThreadPoolSize; ++i)
      {
          boost::shared_ptr&lt;boost::thread&gt; thread(new boost::thread(
                  boost::bind(&amp;OHServer::KeepRunning, this)));
          threads.push_back(thread);
      }
  
      cout &lt;&lt; "Hit enter to close server" &lt;&lt; endl;
      cin.get();
  
  
  }
  
  void OHServer::Stop()
  {
      boost::system::error_code ec;
      _acceptor.close(ec);
  
      _sockClient-&gt;shutdown( boost::asio::ip::tcp::socket::shutdown_both, ec );
      _sockClient-&gt;close( ec );
  
      _io_service.stop();
  
      // Wait for all threads in the pool to exit.
      for (std::size_t i = 0; i &lt; threads.size(); ++i)
      {
          threads[i]-&gt;join();
          cout &lt;&lt; "threads[ "&lt;&lt; i &lt;&lt; "]-&gt;join();" &lt;&lt; endl;
      }
  }
  
  void OHServer::Post()
  {
      std::cout &lt;&lt; "Accepted new connection." &lt;&lt; std::endl;
      CMsgWorker *msgWorker = new CMsgWorker(_sockClient);
      msgWorker-&gt;Start();
      delete msgWorker;
  }
  
  void OHServer::AcceptConnection(const boost::system::error_code&amp; e)
  {
      if (!e)
      {
  
          _io_service.post(boost::bind(&amp;OHServer::Post, this));
  
          _acceptor.async_accept(
                  *_sockClient,
                  boost::bind(
                          &amp;OHServer::AcceptConnection,
                          this,
                          boost::asio::placeholders::error
                  )
          );
  
      }
  }
  </code></pre>
  
  <p>What should I do for the threads to be still waiting for some work to do from _io_service?</p>
  
  <p>Thanks for any help!</p>