diff --git a/lib/src/HttpServer.cc b/lib/src/HttpServer.cc index d75ffd24..5b65bb03 100755 --- a/lib/src/HttpServer.cc +++ b/lib/src/HttpServer.cc @@ -160,7 +160,7 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestPtr &r } HttpServerContext *context = any_cast(conn->getMutableContext()); { - std::lock_guard guard(context->getPipeLineMutex()); + //std::lock_guard guard(context->getPipeLineMutex()); context->pushRquestToPipeLine(req); } httpAsyncCallback_(req, [=](const HttpResponsePtr &response) { @@ -215,6 +215,7 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestPtr &r } delete[] zbuf; } + if (conn->getLoop()->isInLoopThread()) { /* * A client that supports persistent connections MAY “pipeline” @@ -223,7 +224,7 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestPtr &r * requests in the same order that the requests were received. * rfc2616-8.1.1.2 */ - std::lock_guard guard(context->getPipeLineMutex()); + //std::lock_guard guard(context->getPipeLineMutex()); if (context->getFirstRequest() == req) { context->popFirstRequest(); @@ -246,6 +247,33 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestPtr &r context->pushResponseToPipeLine(req, newResp); } } + else + { + conn->getLoop()->queueInLoop([conn, req, newResp, this]() { + HttpServerContext *context = any_cast(conn->getMutableContext()); + if (context->getFirstRequest() == req) + { + context->popFirstRequest(); + sendResponse(conn, newResp); + while (1) + { + auto resp = context->getFirstResponse(); + if (resp) + { + context->popFirstRequest(); + sendResponse(conn, resp); + } + else + return; + } + } + else + { + //some earlier requests are waiting for responses; + context->pushResponseToPipeLine(req, newResp); + } + }); + } }); } void HttpServer::sendResponse(const TcpConnectionPtr &conn, diff --git a/lib/src/HttpServerContext.cc b/lib/src/HttpServerContext.cc index 3ee88956..dd37e9ff 100755 --- a/lib/src/HttpServerContext.cc +++ b/lib/src/HttpServerContext.cc @@ -22,7 +22,6 @@ using namespace drogon; HttpServerContext::HttpServerContext(const trantor::TcpConnectionPtr &connPtr) : state_(kExpectRequestLine), request_(new HttpRequestImpl), - _pipeLineMutex(std::make_shared()), _conn(connPtr) { } @@ -199,12 +198,26 @@ bool HttpServerContext::parseRequest(MsgBuffer *buf) void HttpServerContext::pushRquestToPipeLine(const HttpRequestPtr &req) { +#ifndef NDEBUG + auto conn = _conn.lock(); + if(conn) + { + conn->getLoop()->assertInLoopThread(); + } +#endif std::pair reqPair(req, HttpResponseImplPtr()); _requestPipeLine.push_back(std::move(reqPair)); } HttpRequestPtr HttpServerContext::getFirstRequest() const { +#ifndef NDEBUG + auto conn = _conn.lock(); + if (conn) + { + conn->getLoop()->assertInLoopThread(); + } +#endif if (!_requestPipeLine.empty()) { return _requestPipeLine.front().first; @@ -213,6 +226,13 @@ HttpRequestPtr HttpServerContext::getFirstRequest() const } HttpResponsePtr HttpServerContext::getFirstResponse() const { +#ifndef NDEBUG + auto conn = _conn.lock(); + if (conn) + { + conn->getLoop()->assertInLoopThread(); + } +#endif if (!_requestPipeLine.empty()) { return _requestPipeLine.front().second; @@ -221,11 +241,25 @@ HttpResponsePtr HttpServerContext::getFirstResponse() const } void HttpServerContext::popFirstRequest() { +#ifndef NDEBUG + auto conn = _conn.lock(); + if (conn) + { + conn->getLoop()->assertInLoopThread(); + } +#endif _requestPipeLine.pop_front(); } void HttpServerContext::pushResponseToPipeLine(const HttpRequestPtr &req, const HttpResponsePtr &resp) { +#ifndef NDEBUG + auto conn = _conn.lock(); + if (conn) + { + conn->getLoop()->assertInLoopThread(); + } +#endif for (auto &iter : _requestPipeLine) { if (iter.first == req) @@ -236,7 +270,7 @@ void HttpServerContext::pushResponseToPipeLine(const HttpRequestPtr &req, } } -std::mutex &HttpServerContext::getPipeLineMutex() -{ - return *_pipeLineMutex; -} +// std::mutex &HttpServerContext::getPipeLineMutex() +// { +// return *_pipeLineMutex; +// } diff --git a/lib/src/HttpServerContext.h b/lib/src/HttpServerContext.h index e3e9fa10..84cd78fe 100755 --- a/lib/src/HttpServerContext.h +++ b/lib/src/HttpServerContext.h @@ -85,7 +85,7 @@ class HttpServerContext _websockConnPtr = conn; } //to support request pipelining(rfc2616-8.1.2.2) - std::mutex &getPipeLineMutex(); + //std::mutex &getPipeLineMutex(); void pushRquestToPipeLine(const HttpRequestPtr &req); HttpRequestPtr getFirstRequest() const; HttpResponsePtr getFirstResponse() const; @@ -102,7 +102,7 @@ class HttpServerContext WebSocketConnectionPtr _websockConnPtr; std::list> _requestPipeLine; - std::shared_ptr _pipeLineMutex; + //std::shared_ptr _pipeLineMutex; std::weak_ptr _conn; };