From: Amos Jeffries Date: Sun, 15 Nov 2015 02:54:32 +0000 (-0800) Subject: Add class Pipeline with API for handling client request pipelines X-Git-Tag: SQUID_4_0_3~5^2~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e64903ff96cae201d0771eb31d974e766a6eb78;p=thirdparty%2Fsquid.git Add class Pipeline with API for handling client request pipelines --- diff --git a/src/Pipeline.cc b/src/Pipeline.cc new file mode 100644 index 0000000000..1ee7bda7a2 --- /dev/null +++ b/src/Pipeline.cc @@ -0,0 +1,58 @@ +/* + * Copyright (C) 1996-2015 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +/* + * DEBUG: section 33 Client Request Pipeline + */ +#include "squid.h" +#include "client_side.h" +#include "Debug.h" +#include "Pipeline.h" + +void +Pipeline::add(const ClientSocketContextPointer &c) +{ + requests.push_back(c); + ++nrequests; + debugs(33, 3, "Pipeline " << (void*)this << " add request " << nrequests << ' ' << c); +} + +ClientSocketContextPointer +Pipeline::front() const +{ + if (requests.empty()) { + debugs(33, 3, "Pipeline " << (void*)this << " empty"); + return ClientSocketContextPointer(); + } + + debugs(33, 3, "Pipeline " << (void*)this << " front " << requests.front()); + return requests.front(); +} + +void +Pipeline::terminateAll(int xerrno) +{ + while (!requests.empty()) { + ClientSocketContextPointer context = requests.front(); + debugs(33, 3, "Pipeline " << (void*)this << " notify(" << xerrno << ") " << context); + context->noteIoError(xerrno); + context->connIsFinished(); // cleanup and self-deregister + assert(context != requests.front()); + } +} + +void +Pipeline::pop() +{ + if (requests.empty()) + return; + + debugs(33, 3, "Pipeline " << (void*)this << " drop " << requests.front()); + requests.pop_front(); +} + diff --git a/src/Pipeline.h b/src/Pipeline.h new file mode 100644 index 0000000000..ae040e1dd5 --- /dev/null +++ b/src/Pipeline.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 1996-2015 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#ifndef SQUID_SRC_PIPELINE_H +#define SQUID_SRC_PIPELINE_H + +#include "base/RefCount.h" + +#include + +class ClientSocketContext; +typedef RefCount ClientSocketContextPointer; + +/** + * A queue of requests awaiting completion. + * + * Requests in the queue may be fully processed, but not yet delivered, + * or only partially processed. + * + * - HTTP/1 pipelined requests can be processed out of order but + * responses MUST be written to the client in-order. + * + * - HTTP/2 multiplexed streams (aka requests) can be processed + * and delivered in any order. + * + * For consistency we treat the pipeline as a FIFO queue in both cases. + */ +class Pipeline +{ + Pipeline(const Pipeline &) = delete; + Pipeline & operator =(const Pipeline &) = delete; + +public: + Pipeline() : nrequests(0) {} + ~Pipeline() {terminateAll(0);} + + /// register a new request context to the pipeline + void add(const ClientSocketContextPointer &); + + /// get the first request context in the pipeline + ClientSocketContextPointer front() const; + + /// how many requests are currently pipelined + size_t count() const {return requests.size();} + + /// whether there are none or any requests currently pipelined + bool empty() const {return requests.empty();} + + /// tell everybody about the err, and abort all waiting requests + void terminateAll(const int xerrno); + + /// deregister the front request from the pipeline + void pop(); + + /// Number of requests seen in this pipeline (so far). + /// Includes incomplete transactions. + uint32_t nrequests; + +private: + /// requests parsed from the connection but not yet completed. + std::list requests; +}; + +#endif /* SQUID_SRC_PIPELINE_H */ +