[asio] SSL enabled http server3 example is blocking
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" http://groups.google.pl/group/boost-list/browse_frm/thread/c26432c90020e6d9/81febf05c3db485a?hl=pl&ie=UTF-8&q=SSL+enabled+http+server3+example+is+blocking#81febf05c3db485a 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.
participants (1)
-
Mariusz Wojtysiak