]> git.ipfire.org Git - thirdparty/squid.git/blob - src/comm/AcceptLimiter.cc
Merged from trunk (r13356).
[thirdparty/squid.git] / src / comm / AcceptLimiter.cc
1 #include "squid.h"
2 #include "comm/AcceptLimiter.h"
3 #include "comm/Connection.h"
4 #include "comm/TcpAcceptor.h"
5 #include "fde.h"
6 #include "globals.h"
7
8 Comm::AcceptLimiter Comm::AcceptLimiter::Instance_;
9
10 Comm::AcceptLimiter &
11 Comm::AcceptLimiter::Instance()
12 {
13 return Instance_;
14 }
15
16 void
17 Comm::AcceptLimiter::defer(const Comm::TcpAcceptor::Pointer &afd)
18 {
19 ++ (afd->isLimited);
20 debugs(5, 5, afd->conn << " x" << afd->isLimited);
21 deferred_.push_back(afd);
22 }
23
24 void
25 Comm::AcceptLimiter::removeDead(const Comm::TcpAcceptor::Pointer &afd)
26 {
27 uint64_t abandonedClients = 0;
28 for (unsigned int i = 0; i < deferred_.size() && afd->isLimited > 0; ++i) {
29 if (deferred_[i] == afd) {
30 -- deferred_[i]->isLimited;
31 deferred_[i] = NULL; // fast. kick() will skip empty entries later.
32 debugs(5, 5, afd->conn << " x" << afd->isLimited);
33 ++abandonedClients;
34 }
35 }
36 debugs(5,4, "Abandoned " << abandonedClients << " client TCP SYN by closing socket: " << afd->conn);
37 }
38
39 void
40 Comm::AcceptLimiter::kick()
41 {
42 // TODO: this could be optimized further with an iterator to search
43 // looking for first non-NULL, followed by dumping the first N
44 // with only one shift()/pop_front operation
45 // OR, by reimplementing as a list instead of Vector.
46
47 debugs(5, 5, "size=" << deferred_.size());
48 while (deferred_.size() > 0 && fdNFree() >= RESERVED_FD) {
49 /* NP: shift() is equivalent to pop_front(). Giving us a FIFO queue. */
50 TcpAcceptor::Pointer temp = deferred_.front();
51 deferred_.erase(deferred_.begin());
52 if (temp.valid()) {
53 debugs(5, 5, "doing one.");
54 -- temp->isLimited;
55 temp->acceptNext();
56 break;
57 }
58 }
59 }