]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
bde978a6 | 2 | * Copyright (C) 1996-2015 The Squid Software Foundation and contributors |
bbc27441 AJ |
3 | * |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
7 | */ | |
8 | ||
f7f3304a | 9 | #include "squid.h" |
04f55905 | 10 | #include "comm/AcceptLimiter.h" |
a9870624 | 11 | #include "comm/Connection.h" |
cbff89ba | 12 | #include "comm/TcpAcceptor.h" |
04f55905 | 13 | #include "fde.h" |
582c2af2 | 14 | #include "globals.h" |
04f55905 AJ |
15 | |
16 | Comm::AcceptLimiter Comm::AcceptLimiter::Instance_; | |
17 | ||
69bb9399 AJ |
18 | Comm::AcceptLimiter & |
19 | Comm::AcceptLimiter::Instance() | |
04f55905 AJ |
20 | { |
21 | return Instance_; | |
22 | } | |
23 | ||
24 | void | |
69bb9399 | 25 | Comm::AcceptLimiter::defer(const Comm::TcpAcceptor::Pointer &afd) |
04f55905 | 26 | { |
69bb9399 AJ |
27 | ++ (afd->isLimited); |
28 | debugs(5, 5, afd->conn << " x" << afd->isLimited); | |
29 | deferred_.push_back(afd); | |
04f55905 AJ |
30 | } |
31 | ||
166ba587 | 32 | void |
69bb9399 | 33 | Comm::AcceptLimiter::removeDead(const Comm::TcpAcceptor::Pointer &afd) |
166ba587 | 34 | { |
69bb9399 AJ |
35 | uint64_t abandonedClients = 0; |
36 | for (unsigned int i = 0; i < deferred_.size() && afd->isLimited > 0; ++i) { | |
37 | if (deferred_[i] == afd) { | |
38 | -- deferred_[i]->isLimited; | |
39 | deferred_[i] = NULL; // fast. kick() will skip empty entries later. | |
40 | debugs(5, 5, afd->conn << " x" << afd->isLimited); | |
41 | ++abandonedClients; | |
166ba587 AJ |
42 | } |
43 | } | |
69bb9399 | 44 | debugs(5,4, "Abandoned " << abandonedClients << " client TCP SYN by closing socket: " << afd->conn); |
166ba587 AJ |
45 | } |
46 | ||
04f55905 AJ |
47 | void |
48 | Comm::AcceptLimiter::kick() | |
49 | { | |
2c53add2 AJ |
50 | // TODO: this could be optimized further with an iterator to search |
51 | // looking for first non-NULL, followed by dumping the first N | |
cbff89ba | 52 | // with only one shift()/pop_front operation |
69bb9399 | 53 | // OR, by reimplementing as a list instead of Vector. |
2c53add2 | 54 | |
69bb9399 AJ |
55 | debugs(5, 5, "size=" << deferred_.size()); |
56 | while (deferred_.size() > 0 && fdNFree() >= RESERVED_FD) { | |
04f55905 | 57 | /* NP: shift() is equivalent to pop_front(). Giving us a FIFO queue. */ |
523c3de3 FC |
58 | TcpAcceptor::Pointer temp = deferred_.front(); |
59 | deferred_.erase(deferred_.begin()); | |
69bb9399 AJ |
60 | if (temp.valid()) { |
61 | debugs(5, 5, "doing one."); | |
098346fd | 62 | -- temp->isLimited; |
166ba587 AJ |
63 | temp->acceptNext(); |
64 | break; | |
65 | } | |
04f55905 AJ |
66 | } |
67 | } | |
f53969cc | 68 |