Blame SOURCES/squid-3.5.20-mem-usage-out-of-fd.patch

e6ac7e
diff -up squid-3.5.20/src/comm/AcceptLimiter.cc.02396660 squid-3.5.20/src/comm/AcceptLimiter.cc
e6ac7e
--- squid-3.5.20/src/comm/AcceptLimiter.cc.02396660	2019-06-05 13:18:11.000000000 +0200
e6ac7e
+++ squid-3.5.20/src/comm/AcceptLimiter.cc	2019-06-05 13:21:29.000000000 +0200
e6ac7e
@@ -24,42 +24,33 @@ Comm::AcceptLimiter::Instance()
e6ac7e
 void
e6ac7e
 Comm::AcceptLimiter::defer(const Comm::TcpAcceptor::Pointer &afd)
e6ac7e
 {
e6ac7e
-    ++ (afd->isLimited);
e6ac7e
-    debugs(5, 5, afd->conn << " x" << afd->isLimited);
e6ac7e
+    debugs(5, 5, afd->conn << "; already queued: " << deferred_.size());
e6ac7e
     deferred_.push_back(afd);
e6ac7e
 }
e6ac7e
 
e6ac7e
 void
e6ac7e
 Comm::AcceptLimiter::removeDead(const Comm::TcpAcceptor::Pointer &afd)
e6ac7e
 {
e6ac7e
-    uint64_t abandonedClients = 0;
e6ac7e
-    for (unsigned int i = 0; i < deferred_.size() && afd->isLimited > 0; ++i) {
e6ac7e
-        if (deferred_[i] == afd) {
e6ac7e
-            -- deferred_[i]->isLimited;
e6ac7e
-            deferred_[i] = NULL; // fast. kick() will skip empty entries later.
e6ac7e
-            debugs(5, 5, afd->conn << " x" << afd->isLimited);
e6ac7e
-            ++abandonedClients;
e6ac7e
+    for (auto it = deferred_.begin(); it != deferred_.end(); ++it) {
e6ac7e
+        if (*it == afd) {
e6ac7e
+            *it = nullptr; // fast. kick() will skip empty entries later.
e6ac7e
+            debugs(5,4, "Abandoned client TCP SYN by closing socket: " << afd->conn);
e6ac7e
+            return;
e6ac7e
         }
e6ac7e
     }
e6ac7e
-    debugs(5,4, "Abandoned " << abandonedClients << " client TCP SYN by closing socket: " << afd->conn);
e6ac7e
+    debugs(5,4, "Not found " << afd->conn << " in queue, size: " << deferred_.size());
e6ac7e
 }
e6ac7e
 
e6ac7e
 void
e6ac7e
 Comm::AcceptLimiter::kick()
e6ac7e
 {
e6ac7e
-    // TODO: this could be optimized further with an iterator to search
e6ac7e
-    //       looking for first non-NULL, followed by dumping the first N
e6ac7e
-    //       with only one shift()/pop_front operation
e6ac7e
-    //  OR, by reimplementing as a list instead of Vector.
e6ac7e
-
e6ac7e
     debugs(5, 5, "size=" << deferred_.size());
e6ac7e
-    while (deferred_.size() > 0 && fdNFree() >= RESERVED_FD) {
e6ac7e
+    while (deferred_.size() > 0 && Comm::TcpAcceptor::okToAccept()) {
e6ac7e
         /* NP: shift() is equivalent to pop_front(). Giving us a FIFO queue. */
e6ac7e
         TcpAcceptor::Pointer temp = deferred_.front();
e6ac7e
         deferred_.erase(deferred_.begin());
e6ac7e
         if (temp.valid()) {
e6ac7e
             debugs(5, 5, "doing one.");
e6ac7e
-            -- temp->isLimited;
e6ac7e
             temp->acceptNext();
e6ac7e
             break;
e6ac7e
         }
e6ac7e
diff -up squid-3.5.20/src/comm/AcceptLimiter.h.02396660 squid-3.5.20/src/comm/AcceptLimiter.h
e6ac7e
--- squid-3.5.20/src/comm/AcceptLimiter.h.02396660	2019-06-05 13:18:27.000000000 +0200
e6ac7e
+++ squid-3.5.20/src/comm/AcceptLimiter.h	2019-06-05 13:22:09.000000000 +0200
e6ac7e
@@ -11,7 +11,7 @@
e6ac7e
 
e6ac7e
 #include "comm/TcpAcceptor.h"
e6ac7e
 
e6ac7e
-#include <vector>
e6ac7e
+#include <deque>
e6ac7e
 
e6ac7e
 namespace Comm
e6ac7e
 {
e6ac7e
@@ -26,16 +26,6 @@ namespace Comm
e6ac7e
  * removeDead - used only by Comm layer ConnAcceptor to remove themselves when dying.
e6ac7e
  * kick - used by Comm layer when FD are closed.
e6ac7e
  */
e6ac7e
-/* TODO this algorithm can be optimized further:
e6ac7e
- *
e6ac7e
- * 1) reduce overheads by only pushing one entry per port to the list?
e6ac7e
- * use TcpAcceptor::isLimited as a flag whether to re-list when kick()'ing
e6ac7e
- * or to NULL an entry while scanning the list for empty spaces.
e6ac7e
- * Side effect: TcpAcceptor->kick() becomes allowed to pull off multiple accept()'s in bunches
e6ac7e
- *
e6ac7e
- * 2) re-implement as a std::queue instead of std::vector
e6ac7e
- * storing head/tail pointers for fast push/pop and avoiding the whole shift() overhead
e6ac7e
- */
e6ac7e
 class AcceptLimiter
e6ac7e
 {
e6ac7e
 
e6ac7e
@@ -56,7 +46,7 @@ private:
e6ac7e
     static AcceptLimiter Instance_;
e6ac7e
 
e6ac7e
     /** FIFO queue */
e6ac7e
-    std::vector<TcpAcceptor::Pointer> deferred_;
e6ac7e
+    std::deque<TcpAcceptor::Pointer> deferred_;
e6ac7e
 };
e6ac7e
 
e6ac7e
 }; // namepace Comm
e6ac7e
diff -up squid-3.5.20/src/comm/TcpAcceptor.cc.02396660 squid-3.5.20/src/comm/TcpAcceptor.cc
e6ac7e
--- squid-3.5.20/src/comm/TcpAcceptor.cc.02396660	2019-06-05 13:18:49.000000000 +0200
e6ac7e
+++ squid-3.5.20/src/comm/TcpAcceptor.cc	2019-06-05 13:23:49.000000000 +0200
e6ac7e
@@ -41,7 +41,6 @@ CBDATA_NAMESPACED_CLASS_INIT(Comm, TcpAc
e6ac7e
 Comm::TcpAcceptor::TcpAcceptor(const Comm::ConnectionPointer &newConn, const char *note, const Subscription::Pointer &aSub) :
e6ac7e
     AsyncJob("Comm::TcpAcceptor"),
e6ac7e
     errcode(0),
e6ac7e
-    isLimited(0),
e6ac7e
     theCallSub(aSub),
e6ac7e
     conn(newConn),
e6ac7e
     listenPort_()
e6ac7e
@@ -50,7 +49,6 @@ Comm::TcpAcceptor::TcpAcceptor(const Com
e6ac7e
 Comm::TcpAcceptor::TcpAcceptor(const AnyP::PortCfgPointer &p, const char *note, const Subscription::Pointer &aSub) :
e6ac7e
     AsyncJob("Comm::TcpAcceptor"),
e6ac7e
     errcode(0),
e6ac7e
-    isLimited(0),
e6ac7e
     theCallSub(aSub),
e6ac7e
     conn(p->listenConn),
e6ac7e
     listenPort_(p)
e6ac7e
@@ -227,7 +225,6 @@ Comm::TcpAcceptor::doAccept(int fd, void
e6ac7e
         } else {
e6ac7e
             afd->acceptNext();
e6ac7e
         }
e6ac7e
-        SetSelect(fd, COMM_SELECT_READ, Comm::TcpAcceptor::doAccept, afd, 0);
e6ac7e
 
e6ac7e
     } catch (const std::exception &e) {
e6ac7e
         fatalf("FATAL: error while accepting new client connection: %s\n", e.what());
e6ac7e
@@ -286,6 +283,7 @@ Comm::TcpAcceptor::acceptOne()
e6ac7e
            " accepted new connection " << newConnDetails <<
e6ac7e
            " handler Subscription: " << theCallSub);
e6ac7e
     notify(flag, newConnDetails);
e6ac7e
+    SetSelect(conn->fd, COMM_SELECT_READ, doAccept, this, 0);
e6ac7e
 }
e6ac7e
 
e6ac7e
 void
e6ac7e
diff -up squid-3.5.20/src/comm/TcpAcceptor.h.02396660 squid-3.5.20/src/comm/TcpAcceptor.h
e6ac7e
--- squid-3.5.20/src/comm/TcpAcceptor.h.02396660	2019-06-05 13:18:57.000000000 +0200
e6ac7e
+++ squid-3.5.20/src/comm/TcpAcceptor.h	2019-06-05 13:25:05.000000000 +0200
e6ac7e
@@ -74,9 +74,12 @@ public:
e6ac7e
     /// errno code of the last accept() or listen() action if one occurred.
e6ac7e
     int errcode;
e6ac7e
 
e6ac7e
+    /// Method to test if there are enough file descriptors to open a new client connection
e6ac7e
+    /// if not the accept() will be postponed
e6ac7e
+    static bool okToAccept();
e6ac7e
+
e6ac7e
 protected:
e6ac7e
     friend class AcceptLimiter;
e6ac7e
-    int32_t isLimited;                   ///< whether this socket is delayed and on the AcceptLimiter queue.
e6ac7e
 
e6ac7e
 private:
e6ac7e
     Subscription::Pointer theCallSub;    ///< used to generate AsyncCalls handling our events.
e6ac7e
@@ -91,10 +94,6 @@ private:
e6ac7e
     /// listen socket closure handler
e6ac7e
     AsyncCall::Pointer closer_;
e6ac7e
 
e6ac7e
-    /// Method to test if there are enough file descriptors to open a new client connection
e6ac7e
-    /// if not the accept() will be postponed
e6ac7e
-    static bool okToAccept();
e6ac7e
-
e6ac7e
     /// Method callback for whenever an FD is ready to accept a client connection.
e6ac7e
     static void doAccept(int fd, void *data);
e6ac7e