]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Add class Pipeline with API for handling client request pipelines
authorAmos Jeffries <squid3@treenet.co.nz>
Sun, 15 Nov 2015 02:54:32 +0000 (18:54 -0800)
committerAmos Jeffries <squid3@treenet.co.nz>
Sun, 15 Nov 2015 02:54:32 +0000 (18:54 -0800)
src/Pipeline.cc [new file with mode: 0644]
src/Pipeline.h [new file with mode: 0644]

diff --git a/src/Pipeline.cc b/src/Pipeline.cc
new file mode 100644 (file)
index 0000000..1ee7bda
--- /dev/null
@@ -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 (file)
index 0000000..ae040e1
--- /dev/null
@@ -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 <list>
+
+class ClientSocketContext;
+typedef RefCount<ClientSocketContext> 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<ClientSocketContextPointer> requests;
+};
+
+#endif /* SQUID_SRC_PIPELINE_H */
+