|
Boost Users : |
Subject: [Boost-users] [asio] SSL enabled http server3 example is blocking
From: Mariusz Wojtysiak (zxspeccy.cpp_at_[hidden])
Date: 2009-09-07 08:11:57
Hello,
I noticed, that my ssl server implemented with boost::asio, which use
pool of 10 threads, use only first working thread.
Even if I put long running operation (like: std::cin > c; ) in handler
of ssl request, request from second client is hung until running
operation finish in first thread.
Similar problem was described in archived post: "[asio] SSL enabled
http server3 example is blocking"
After a few hours of debugging asio, I found a reason:
Class openssl_stream_service implement ssl operations (like
async_handshake, async_write_some...) using strand_ member, which is
type of io_service::strand.
This causes that two ssl operations using the same ssl stream cannot
be running in the same time.
Here is piece of code, which I had on my server to handle client
request:
void Request::handleClientRequest()
{
boost::asio::async_read_until( m_sessionPtr->getSocket(),
m_headerBuffer, '\n',
boost::bind( &Request::readHeaderHandler, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred ) );
}
void Request::readHeaderHandler( const boost::system::error_code
&error, std::size_t bytesTransferred )
{
// long running operation
char c;
}
Method readHeaderHandler() is called from io_service::strand, so
during this long running operation any other requests from clients
have to wait!
Solution it simple and works fine for me:
Instead of calling long operations directly in handler, post operation
to io_service, like here:
void Request::readHeaderHandler( const boost::system::error_code
&error, std::size_t bytesTransferred )
{
m_ioService.post( boost::bind
( &Request::executeCommandHandler::executeCommandHandler,
shared_from_this() ) );
}
void Request::executeCommandHandler()
{
// long running operation
char c;
}
This way, readHeaderHandler() return immediately from current srand
operation (so other client's request may be handled) and
executeCommandHandler() is called a bit later.
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