]> git.ipfire.org Git - thirdparty/squid.git/blob - src/comm/AcceptLimiter.cc
Bug 2581, Bug 3081, Bug 2948: various TCP socket connection problems
[thirdparty/squid.git] / src / comm / AcceptLimiter.cc
1 #include "config.h"
2 #include "comm/AcceptLimiter.h"
3 #include "comm/TcpAcceptor.h"
4 #include "fde.h"
5
6 Comm::AcceptLimiter Comm::AcceptLimiter::Instance_;
7
8 Comm::AcceptLimiter &Comm::AcceptLimiter::Instance()
9 {
10 return Instance_;
11 }
12
13 void
14 Comm::AcceptLimiter::defer(Comm::TcpAcceptor *afd)
15 {
16 afd->isLimited++;
17 debugs(5, 5, HERE << "FD " << afd->fd << " x" << afd->isLimited);
18 deferred.push_back(afd);
19 }
20
21 void
22 Comm::AcceptLimiter::removeDead(const Comm::TcpAcceptor *afd)
23 {
24 for (unsigned int i = 0; i < deferred.size() && afd->isLimited > 0; i++) {
25 if (deferred[i] == afd) {
26 deferred[i]->isLimited--;
27 deferred[i] = NULL; // fast. kick() will skip empty entries later.
28 debugs(5, 5, HERE << "FD " << afd->fd << " x" << afd->isLimited);
29 }
30 }
31 }
32
33 void
34 Comm::AcceptLimiter::kick()
35 {
36 // TODO: this could be optimized further with an iterator to search
37 // looking for first non-NULL, followed by dumping the first N
38 // with only one shift()/pop_front operation
39
40 debugs(5, 5, HERE << " size=" << deferred.size());
41 while (deferred.size() > 0 && fdNFree() >= RESERVED_FD) {
42 /* NP: shift() is equivalent to pop_front(). Giving us a FIFO queue. */
43 TcpAcceptor *temp = deferred.shift();
44 if (temp != NULL) {
45 debugs(5, 5, HERE << " doing one.");
46 temp->isLimited--;
47 temp->acceptNext();
48 break;
49 }
50 }
51 }