Boost logo

Boost Users :

Subject: [Boost-users] Multithreaded HTTP server
From: Alex Black (alex_at_[hidden])
Date: 2009-07-22 23:25:17


Does this code look ok? Specifically, does this look like a good way to
have a fixed # of threads service requests, and have each thread
asychronously write out the response to their client?
 
In the code below, I left out HandleHttpRequest, and that function
parses the request, does some work, and writes out the response 8kb at a
type, using async_write.
 
note: the threads don't wait until the previous async_write is done,
they each just keep calling async_write until all their data is out.
(but they are careful to make sure their buffers are around for long
enough)
 
void CBaseWebServer::StartAsync(int port)
{
 m_pAcceptor = shared_ptr<tcp::acceptor>( new tcp::acceptor(m_IoService,
tcp::endpoint(tcp::v4(), port)) );
 
 // Find out how many threads we shoudl run
 int numberOfThreads = boost::thread::hardware_concurrency();
 
 StartAccept();
 
 for ( int i = 0; i < numberOfThreads; i++ )
 {
  // Fire up a thread to run the IO service
  shared_ptr<thread> pThread = shared_ptr<thread>(new
thread(bind(&CBaseWebServer::RunIoService, this, i)));
 
  m_Threads.push_back(pThread);
 }
}
 
void CBaseWebServer::RunIoService(int threadId)
{
 m_pPerThreadId.reset( new int(threadId) );
 cout << "Starting thread: " << threadId << endl;
 
 try
 {
  m_IoService.run();
 }
 catch ( ... )
 {
  cout << "Unexpected exception caught in " << BOOST_CURRENT_FUNCTION <<
endl << boost::current_exception_diagnostic_information();
 }
}
 
void CBaseWebServer::StartAccept()
{
 try
 {
  shared_ptr<tcp::socket> pSocket(new tcp::socket(m_IoService));
 
  m_pAcceptor->async_accept(*pSocket,
bind(&CBaseWebServer::HandleAccept, this, pSocket,
boost::asio::placeholders::error));
 }
 catch ( ... )
 {
  cout << "Unexpected exception caught in " << BOOST_CURRENT_FUNCTION <<
endl << boost::current_exception_diagnostic_information();
 }
}
 
void CBaseWebServer::HandleAccept(shared_ptr<tcp::socket> pSocket, const
boost::system::error_code& error)
{
 if ( !error )
 {
  try
  {
   HandleHTTPRequest(pSocket);
  }
  catch ( ... )
  {
   cout << "Unexpected exception caught in " << BOOST_CURRENT_FUNCTION
<< endl << boost::current_exception_diagnostic_information();
  }
 
  StartAccept();
 }
 else
 {
  cout << "CBaseWebServer::HandleAccept received error: " <<
error.message().c_str() << endl;
 }
}



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net