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;
}
}