ModSelect.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
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 
9 /* DEBUG: section 05 Socket Functions */
10 
11 #include "squid.h"
12 
13 #if USE_SELECT
14 
15 #include "anyp/PortCfg.h"
16 #include "comm/Connection.h"
17 #include "comm/Loops.h"
18 #include "fde.h"
19 #include "globals.h"
20 #include "ICP.h"
21 #include "mgr/Registration.h"
22 #include "SquidConfig.h"
23 #include "StatCounters.h"
24 #include "StatHist.h"
25 #include "Store.h"
26 
27 #include <cerrno>
28 #if HAVE_SYS_STAT_H
29 #include <sys/stat.h>
30 #endif
31 
32 static int MAX_POLL_TIME = 1000; /* see also Comm::QuickPollRequired() */
33 
34 #ifndef howmany
35 #define howmany(x, y) (((x)+((y)-1))/(y))
36 #endif
37 #ifndef NBBY
38 #define NBBY 8
39 #endif
40 #define FD_MASK_BYTES sizeof(fd_mask)
41 #define FD_MASK_BITS (FD_MASK_BYTES*NBBY)
42 
43 /* STATIC */
44 static int examine_select(fd_set *, fd_set *);
45 static int fdIsTcpListener(int fd);
46 static int fdIsUdpListener(int fd);
47 static int fdIsDns(int fd);
49 static int comm_check_incoming_select_handlers(int nfds, int *fds);
50 static void comm_select_dns_incoming(void);
51 static void commUpdateReadBits(int fd, PF * handler);
52 static void commUpdateWriteBits(int fd, PF * handler);
53 
54 static struct timeval zero_tv;
55 static fd_set global_readfds;
56 static fd_set global_writefds;
57 static int nreadfds;
58 static int nwritefds;
59 
60 /*
61  * Automatic tuning for incoming requests:
62  *
63  * INCOMING sockets are the ICP and HTTP ports. We need to check these
64  * fairly regularly, but how often? When the load increases, we
65  * want to check the incoming sockets more often. If we have a lot
66  * of incoming ICP, then we need to check these sockets more than
67  * if we just have HTTP.
68  *
69  * The variables 'incoming_udp_interval' and 'incoming_tcp_interval'
70  * determine how many normal I/O events to process before checking
71  * incoming sockets again. Note we store the incoming_interval
72  * multiplied by a factor of (2^INCOMING_FACTOR) to have some
73  * pseudo-floating point precision.
74  *
75  * The variable 'udp_io_events' and 'tcp_io_events' counts how many normal
76  * I/O events have been processed since the last check on the incoming
77  * sockets. When io_events > incoming_interval, its time to check incoming
78  * sockets.
79  *
80  * Every time we check incoming sockets, we count how many new messages
81  * or connections were processed. This is used to adjust the
82  * incoming_interval for the next iteration. The new incoming_interval
83  * is calculated as the current incoming_interval plus what we would
84  * like to see as an average number of events minus the number of
85  * events just processed.
86  *
87  * incoming_interval = incoming_interval + target_average - number_of_events_processed
88  *
89  * There are separate incoming_interval counters for DNS, UDP and TCP events
90  *
91  * You can see the current values of the incoming_interval's, as well as
92  * a histogram of 'incoming_events' by asking the cache manager
93  * for 'comm_incoming', e.g.:
94  *
95  * % ./client mgr:comm_incoming
96  *
97  * Caveats:
98  *
99  * - We have MAX_INCOMING_INTEGER as a magic upper limit on
100  * incoming_interval for both types of sockets. At the
101  * largest value the cache will effectively be idling.
102  *
103  * - The higher the INCOMING_FACTOR, the slower the algorithm will
104  * respond to load spikes/increases/decreases in demand. A value
105  * between 3 and 8 is recommended.
106  */
107 
108 #define MAX_INCOMING_INTEGER 256
109 #define INCOMING_FACTOR 5
110 #define MAX_INCOMING_INTERVAL (MAX_INCOMING_INTEGER << INCOMING_FACTOR)
111 static int udp_io_events = 0;
112 static int dns_io_events = 0;
113 static int tcp_io_events = 0;
117 #define commCheckUdpIncoming (++udp_io_events > (incoming_udp_interval>> INCOMING_FACTOR))
118 #define commCheckDnsIncoming (++dns_io_events > (incoming_dns_interval>> INCOMING_FACTOR))
119 #define commCheckTcpIncoming (++tcp_io_events > (incoming_tcp_interval>> INCOMING_FACTOR))
120 
121 void
122 Comm::SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time_t timeout)
123 {
124  fde *F = &fd_table[fd];
125  assert(fd >= 0);
126  assert(F->flags.open || (!handler && !client_data && !timeout));
127  debugs(5, 5, "FD " << fd << ", type=" << type <<
128  ", handler=" << handler << ", client_data=" << client_data <<
129  ", timeout=" << timeout);
130 
131  if (type & COMM_SELECT_READ) {
132  F->read_handler = handler;
133  F->read_data = client_data;
135  }
136 
137  if (type & COMM_SELECT_WRITE) {
138  F->write_handler = handler;
139  F->write_data = client_data;
141  }
142 
143  if (timeout)
144  F->timeout = squid_curtime + timeout;
145 }
146 
147 static int
149 {
150  if (icpIncomingConn != nullptr && fd == icpIncomingConn->fd)
151  return 1;
152 
153  if (icpOutgoingConn != nullptr && fd == icpOutgoingConn->fd)
154  return 1;
155 
156  return 0;
157 }
158 
159 static int
160 fdIsDns(int fd)
161 {
162  if (fd == DnsSocketA)
163  return 1;
164 
165  if (fd == DnsSocketB)
166  return 1;
167 
168  return 0;
169 }
170 
171 static int
173 {
174  for (AnyP::PortCfgPointer s = HttpPortList; s != nullptr; s = s->next) {
175  if (s->listenConn != nullptr && s->listenConn->fd == fd)
176  return 1;
177  }
178 
179  return 0;
180 }
181 
182 static int
184 {
185  int i;
186  int fd;
187  int maxfd = 0;
188  PF *hdl = nullptr;
189  fd_set read_mask;
190  fd_set write_mask;
191  FD_ZERO(&read_mask);
192  FD_ZERO(&write_mask);
194 
195  for (i = 0; i < nfds; ++i) {
196  fd = fds[i];
197 
198  if (fd_table[fd].read_handler) {
199  FD_SET(fd, &read_mask);
200 
201  if (fd > maxfd)
202  maxfd = fd;
203  }
204 
205  if (fd_table[fd].write_handler) {
206  FD_SET(fd, &write_mask);
207 
208  if (fd > maxfd)
209  maxfd = fd;
210  }
211  }
212 
213  if (maxfd++ == 0)
214  return -1;
215 
216  getCurrentTime();
217 
219 
220  if (select(maxfd, &read_mask, &write_mask, nullptr, &zero_tv) < 1)
222 
223  for (i = 0; i < nfds; ++i) {
224  fd = fds[i];
225 
226  if (FD_ISSET(fd, &read_mask)) {
227  if ((hdl = fd_table[fd].read_handler) != nullptr) {
228  fd_table[fd].read_handler = nullptr;
229  commUpdateReadBits(fd, nullptr);
230  hdl(fd, fd_table[fd].read_data);
231  } else {
232  debugs(5, DBG_IMPORTANT, "comm_select_incoming: FD " << fd << " NULL read handler");
233  }
234  }
235 
236  if (FD_ISSET(fd, &write_mask)) {
237  if ((hdl = fd_table[fd].write_handler) != nullptr) {
238  fd_table[fd].write_handler = nullptr;
239  commUpdateWriteBits(fd, nullptr);
240  hdl(fd, fd_table[fd].write_data);
241  } else {
242  debugs(5, DBG_IMPORTANT, "comm_select_incoming: FD " << fd << " NULL write handler");
243  }
244  }
245  }
246 
248 }
249 
250 static void
252 {
253  int nfds = 0;
254  int fds[2];
255  int nevents;
256  udp_io_events = 0;
257 
259  fds[nfds] = icpIncomingConn->fd;
260  ++nfds;
261  }
262 
264  fds[nfds] = icpOutgoingConn->fd;
265  ++nfds;
266  }
267 
268  if (nfds == 0)
269  return;
270 
272 
273  incoming_udp_interval += Config.comm_incoming.udp.average - nevents;
274 
275  if (incoming_udp_interval < 0)
277 
280 
281  if (nevents > INCOMING_UDP_MAX)
282  nevents = INCOMING_UDP_MAX;
283 
285 }
286 
287 static void
289 {
290  int nfds = 0;
291  int fds[MAXTCPLISTENPORTS];
292  int nevents;
293  tcp_io_events = 0;
294 
295  // XXX: only poll sockets that won't be deferred. But how do we identify them?
296 
297  for (AnyP::PortCfgPointer s = HttpPortList; s != nullptr; s = s->next) {
298  if (Comm::IsConnOpen(s->listenConn)) {
299  fds[nfds] = s->listenConn->fd;
300  ++nfds;
301  }
302  }
303 
305  incoming_tcp_interval += Config.comm_incoming.tcp.average - nevents;
306 
307  if (incoming_tcp_interval < 0)
309 
312 
313  if (nevents > INCOMING_TCP_MAX)
314  nevents = INCOMING_TCP_MAX;
315 
317 }
318 
319 /* Select on all sockets; call handlers for those that are ready. */
321 Comm::DoSelect(int msec)
322 {
323  fd_set readfds;
324  fd_set pendingfds;
325  fd_set writefds;
326 
327  PF *hdl = nullptr;
328  int fd;
329  int maxfd;
330  int num;
331  int pending;
332  int calldns = 0, calludp = 0, calltcp = 0;
333  int maxindex;
334  unsigned int k;
335  int j;
336  fd_mask *fdsp;
337  fd_mask *pfdsp;
338  fd_mask tmask;
339 
340  struct timeval poll_time;
341  double timeout = current_dtime + (msec / 1000.0);
342  fde *F;
343 
344  do {
345  double start;
346  getCurrentTime();
347  start = current_dtime;
348 
351 
354 
357 
358  calldns = calludp = calltcp = 0;
359 
360  maxfd = Biggest_FD + 1;
361 
362  memcpy(&readfds, &global_readfds,
364 
365  memcpy(&writefds, &global_writefds,
367 
368  /* remove stalled FDs, and deal with pending descriptors */
369  pending = 0;
370 
371  FD_ZERO(&pendingfds);
372 
373  maxindex = howmany(maxfd, FD_MASK_BITS);
374 
375  fdsp = (fd_mask *) & readfds;
376 
377  for (j = 0; j < maxindex; ++j) {
378  if ((tmask = fdsp[j]) == 0)
379  continue; /* no bits here */
380 
381  for (k = 0; k < FD_MASK_BITS; ++k) {
382  if (!EBIT_TEST(tmask, k))
383  continue;
384 
385  /* Found a set bit */
386  fd = (j * FD_MASK_BITS) + k;
387 
388  if (FD_ISSET(fd, &readfds) && fd_table[fd].flags.read_pending) {
389  FD_SET(fd, &pendingfds);
390  ++pending;
391  }
392  }
393  }
394 
395  if (nreadfds + nwritefds == 0) {
397  return Comm::SHUTDOWN;
398  }
399 
400  if (msec > MAX_POLL_TIME)
401  msec = MAX_POLL_TIME;
402 
403  if (pending)
404  msec = 0;
405 
406  for (;;) {
407  poll_time.tv_sec = msec / 1000;
408  poll_time.tv_usec = (msec % 1000) * 1000;
410  num = select(maxfd, &readfds, &writefds, nullptr, &poll_time);
411  int xerrno = errno;
413 
414  if (num >= 0 || pending > 0)
415  break;
416 
417  if (ignoreErrno(xerrno))
418  break;
419 
420  debugs(5, DBG_CRITICAL, MYNAME << "select failure: " << xstrerr(xerrno));
421 
422  examine_select(&readfds, &writefds);
423 
424  return Comm::COMM_ERROR;
425 
426  /* NOTREACHED */
427  }
428 
429  if (num < 0 && !pending)
430  continue;
431 
432  getCurrentTime();
433 
434  debugs(5, num ? 5 : 8, "comm_select: " << num << "+" << pending << " FDs ready");
435 
437 
438  if (num == 0 && pending == 0)
439  continue;
440 
441  /* Scan return fd masks for ready descriptors */
442  fdsp = (fd_mask *) & readfds;
443 
444  pfdsp = (fd_mask *) & pendingfds;
445 
446  maxindex = howmany(maxfd, FD_MASK_BITS);
447 
448  for (j = 0; j < maxindex; ++j) {
449  if ((tmask = (fdsp[j] | pfdsp[j])) == 0)
450  continue; /* no bits here */
451 
452  for (k = 0; k < FD_MASK_BITS; ++k) {
453  if (tmask == 0)
454  break; /* no more bits left */
455 
456  if (!EBIT_TEST(tmask, k))
457  continue;
458 
459  /* Found a set bit */
460  fd = (j * FD_MASK_BITS) + k;
461 
462  EBIT_CLR(tmask, k); /* this will be done */
463 
464  if (fdIsUdpListener(fd)) {
465  calludp = 1;
466  continue;
467  }
468 
469  if (fdIsDns(fd)) {
470  calldns = 1;
471  continue;
472  }
473 
474  if (fdIsTcpListener(fd)) {
475  calltcp = 1;
476  continue;
477  }
478 
479  F = &fd_table[fd];
480  debugs(5, 6, "comm_select: FD " << fd << " ready for reading");
481 
482  if (nullptr == (hdl = F->read_handler))
483  (void) 0;
484  else {
485  F->read_handler = nullptr;
486  commUpdateReadBits(fd, nullptr);
487  hdl(fd, F->read_data);
489 
492 
495 
498  }
499  }
500  }
501 
502  fdsp = (fd_mask *) & writefds;
503 
504  for (j = 0; j < maxindex; ++j) {
505  if ((tmask = fdsp[j]) == 0)
506  continue; /* no bits here */
507 
508  for (k = 0; k < FD_MASK_BITS; ++k) {
509  if (tmask == 0)
510  break; /* no more bits left */
511 
512  if (!EBIT_TEST(tmask, k))
513  continue;
514 
515  /* Found a set bit */
516  fd = (j * FD_MASK_BITS) + k;
517 
518  EBIT_CLR(tmask, k); /* this will be done */
519 
520  if (fdIsUdpListener(fd)) {
521  calludp = 1;
522  continue;
523  }
524 
525  if (fdIsDns(fd)) {
526  calldns = 1;
527  continue;
528  }
529 
530  if (fdIsTcpListener(fd)) {
531  calltcp = 1;
532  continue;
533  }
534 
535  F = &fd_table[fd];
536  debugs(5, 6, "comm_select: FD " << fd << " ready for writing");
537 
538  if ((hdl = F->write_handler)) {
539  F->write_handler = nullptr;
540  commUpdateWriteBits(fd, nullptr);
541  hdl(fd, F->write_data);
543 
546 
549 
552  }
553  }
554  }
555 
556  if (calludp)
558 
559  if (calldns)
561 
562  if (calltcp)
564 
565  getCurrentTime();
566 
568 
569  return Comm::OK;
570  } while (timeout > current_dtime);
571  debugs(5, 8, "comm_select: time out: " << squid_curtime);
572 
573  return Comm::TIMEOUT;
574 }
575 
576 static void
578 {
579  int nfds = 0;
580  int fds[3];
581  int nevents;
582  dns_io_events = 0;
583 
584  if (DnsSocketA < 0 && DnsSocketB < 0)
585  return;
586 
587  if (DnsSocketA >= 0) {
588  fds[nfds] = DnsSocketA;
589  ++nfds;
590  }
591 
592  if (DnsSocketB >= 0) {
593  fds[nfds] = DnsSocketB;
594  ++nfds;
595  }
596 
598 
599  if (nevents < 0)
600  return;
601 
602  incoming_dns_interval += Config.comm_incoming.dns.average - nevents;
603 
606 
609 
610  if (nevents > INCOMING_DNS_MAX)
611  nevents = INCOMING_DNS_MAX;
612 
614 }
615 
616 void
618 {
619  zero_tv.tv_sec = 0;
620  zero_tv.tv_usec = 0;
621  FD_ZERO(&global_readfds);
622  FD_ZERO(&global_writefds);
623  nreadfds = nwritefds = 0;
624 
625  Mgr::RegisterAction("comm_select_incoming",
626  "comm_incoming() stats",
627  commIncomingStats, 0, 1);
628 }
629 
630 /*
631  * examine_select - debug routine.
632  *
633  * I spend the day chasing this core dump that occurs when both the client
634  * and the server side of a cache fetch simultaneoulsy abort the
635  * connection. While I haven't really studied the code to figure out how
636  * it happens, the snippet below may prevent the cache from exitting:
637  *
638  * Call this from where the select loop fails.
639  */
640 static int
641 examine_select(fd_set * readfds, fd_set * writefds)
642 {
643  int fd = 0;
644  fd_set read_x;
645  fd_set write_x;
646 
647  struct timeval tv;
648  AsyncCall::Pointer ch = nullptr;
649  fde *F = nullptr;
650 
651  struct stat sb;
652  debugs(5, DBG_CRITICAL, "examine_select: Examining open file descriptors...");
653 
654  for (fd = 0; fd < Squid_MaxFD; ++fd) {
655  FD_ZERO(&read_x);
656  FD_ZERO(&write_x);
657  tv.tv_sec = tv.tv_usec = 0;
658 
659  if (FD_ISSET(fd, readfds))
660  FD_SET(fd, &read_x);
661  else if (FD_ISSET(fd, writefds))
662  FD_SET(fd, &write_x);
663  else
664  continue;
665 
667  errno = 0;
668 
669  if (!fstat(fd, &sb)) {
670  debugs(5, 5, "FD " << fd << " is valid.");
671  continue;
672  }
673  int xerrno = errno;
674 
675  F = &fd_table[fd];
676  debugs(5, DBG_CRITICAL, "fstat(FD " << fd << "): " << xstrerr(xerrno));
677  debugs(5, DBG_CRITICAL, "WARNING: FD " << fd << " has handlers, but it's invalid.");
678  debugs(5, DBG_CRITICAL, "FD " << fd << " is a " << fdTypeStr[F->type] << " called '" << F->desc << "'");
679  debugs(5, DBG_CRITICAL, "tmout:" << F->timeoutHandler << " read:" << F->read_handler << " write:" << F->write_handler);
680 
681  for (ch = F->closeHandler; ch != nullptr; ch = ch->Next())
682  debugs(5, DBG_CRITICAL, " close handler: " << ch);
683 
684  if (F->closeHandler != nullptr) {
686  } else if (F->timeoutHandler != nullptr) {
687  debugs(5, DBG_CRITICAL, "examine_select: Calling Timeout Handler");
688  ScheduleCallHere(F->timeoutHandler);
689  }
690 
691  F->closeHandler = nullptr;
692  F->timeoutHandler = nullptr;
693  F->read_handler = nullptr;
694  F->write_handler = nullptr;
695  FD_CLR(fd, readfds);
696  FD_CLR(fd, writefds);
697  }
698 
699  return 0;
700 }
701 
702 static void
704 {
705  storeAppendPrintf(sentry, "Current incoming_udp_interval: %d\n",
707  storeAppendPrintf(sentry, "Current incoming_dns_interval: %d\n",
709  storeAppendPrintf(sentry, "Current incoming_tcp_interval: %d\n",
711  storeAppendPrintf(sentry, "\n");
712  storeAppendPrintf(sentry, "Histogram of events per incoming socket type\n");
713  storeAppendPrintf(sentry, "ICP Messages handled per comm_select_udp_incoming() call:\n");
715  storeAppendPrintf(sentry, "DNS Messages handled per comm_select_dns_incoming() call:\n");
717  storeAppendPrintf(sentry, "HTTP Messages handled per comm_select_tcp_incoming() call:\n");
719 }
720 
721 void
723 {
724  if (handler && !FD_ISSET(fd, &global_readfds)) {
725  FD_SET(fd, &global_readfds);
726  ++nreadfds;
727  } else if (!handler && FD_ISSET(fd, &global_readfds)) {
728  FD_CLR(fd, &global_readfds);
729  --nreadfds;
730  }
731 }
732 
733 void
735 {
736  if (handler && !FD_ISSET(fd, &global_writefds)) {
737  FD_SET(fd, &global_writefds);
738  ++nwritefds;
739  } else if (!handler && FD_ISSET(fd, &global_writefds)) {
740  FD_CLR(fd, &global_writefds);
741  --nwritefds;
742  }
743 }
744 
745 /* Called by async-io or diskd to speed up the polling */
746 void
748 {
749  MAX_POLL_TIME = 10;
750 }
751 
752 #endif /* USE_SELECT */
753 
#define ScheduleCallHere(call)
Definition: AsyncCall.h:164
#define INCOMING_TCP_MAX
Definition: Loops.h:69
#define INCOMING_DNS_MAX
Definition: Loops.h:59
#define INCOMING_UDP_MAX
Definition: Loops.h:50
static fd_set global_readfds
Definition: ModSelect.cc:55
static int fdIsTcpListener(int fd)
Definition: ModSelect.cc:172
static int incoming_udp_interval
Definition: ModSelect.cc:114
#define commCheckTcpIncoming
Definition: ModSelect.cc:119
static int incoming_tcp_interval
Definition: ModSelect.cc:116
static int fdIsDns(int fd)
Definition: ModSelect.cc:160
static void commUpdateReadBits(int fd, PF *handler)
Definition: ModSelect.cc:722
#define FD_MASK_BITS
Definition: ModSelect.cc:41
static void comm_select_udp_incoming(void)
Definition: ModSelect.cc:251
static int incoming_dns_interval
Definition: ModSelect.cc:115
static int dns_io_events
Definition: ModSelect.cc:112
static int tcp_io_events
Definition: ModSelect.cc:113
static int nreadfds
Definition: ModSelect.cc:57
#define howmany(x, y)
Definition: ModSelect.cc:35
static int nwritefds
Definition: ModSelect.cc:58
static int MAX_POLL_TIME
Definition: ModSelect.cc:32
#define commCheckDnsIncoming
Definition: ModSelect.cc:118
#define commCheckUdpIncoming
Definition: ModSelect.cc:117
#define FD_MASK_BYTES
Definition: ModSelect.cc:40
static void comm_select_tcp_incoming(void)
Definition: ModSelect.cc:288
static struct timeval zero_tv
Definition: ModSelect.cc:54
static int examine_select(fd_set *, fd_set *)
Definition: ModSelect.cc:641
static int fdIsUdpListener(int fd)
Definition: ModSelect.cc:148
static int comm_check_incoming_select_handlers(int nfds, int *fds)
Definition: ModSelect.cc:183
#define INCOMING_FACTOR
Definition: ModSelect.cc:109
static OBJH commIncomingStats
Definition: ModSelect.cc:48
static int udp_io_events
Definition: ModSelect.cc:111
#define MAX_INCOMING_INTERVAL
Definition: ModSelect.cc:110
static void commUpdateWriteBits(int fd, PF *handler)
Definition: ModSelect.cc:734
static fd_set global_writefds
Definition: ModSelect.cc:56
static void comm_select_dns_incoming(void)
Definition: ModSelect.cc:577
time_t squid_curtime
Definition: stub_libtime.cc:20
AnyP::PortCfgPointer HttpPortList
list of Squid http(s)_port configured
Definition: PortCfg.cc:22
#define MAXTCPLISTENPORTS
Definition: PortCfg.h:87
class SquidConfig Config
Definition: SquidConfig.cc:12
StatCounters statCounter
Definition: StatCounters.cc:12
StatHistBinDumper statHistIntDumper
Definition: StatHist.h:119
#define assert(EX)
Definition: assert.h:19
struct SquidConfig::@116::@124 tcp
struct SquidConfig::@116 comm_incoming
struct SquidConfig::@116::@124 dns
struct SquidConfig::@116::@124 udp
double select_time
Definition: StatCounters.h:120
StatHist select_fds_hist
Definition: StatCounters.h:127
struct StatCounters::@135 syscalls
StatHist comm_tcp_incoming
Definition: StatCounters.h:126
unsigned long int select_loops
Definition: StatCounters.h:118
StatHist comm_udp_incoming
Definition: StatCounters.h:124
StatHist comm_dns_incoming
Definition: StatCounters.h:125
void count(double val)
Definition: StatHist.cc:55
void dump(StoreEntry *sentry, StatHistBinDumper *bd) const
Definition: StatHist.cc:171
Definition: fde.h:52
void PF(int, void *)
Definition: forward.h:18
void commCallCloseHandlers(int fd)
Definition: comm.cc:727
int ignoreErrno(int ierrno)
Definition: comm.cc:1412
#define MYNAME
Definition: Stream.h:238
#define DBG_IMPORTANT
Definition: Stream.h:41
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
#define DBG_CRITICAL
Definition: Stream.h:40
#define COMM_SELECT_READ
Definition: defines.h:24
#define EBIT_CLR(flag, bit)
Definition: defines.h:68
#define COMM_SELECT_WRITE
Definition: defines.h:25
#define EBIT_TEST(flag, bit)
Definition: defines.h:69
int type
Definition: errorpage.cc:152
const char * fdTypeStr[]
Definition: fd.cc:39
#define fd_table
Definition: fde.h:189
int DnsSocketB
int DnsSocketA
int shutting_down
int Squid_MaxFD
int Biggest_FD
int incoming_sockets_accepted
Comm::ConnectionPointer icpOutgoingConn
Definition: icp_v2.cc:100
Comm::ConnectionPointer icpIncomingConn
Definition: icp_v2.cc:98
static uint32 F(uint32 X, uint32 Y, uint32 Z)
Definition: md4.c:46
void OBJH(StoreEntry *)
Definition: forward.h:44
void QuickPollRequired(void)
Definition: ModDevPoll.cc:417
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:27
Flag
Definition: Flag.h:15
@ SHUTDOWN
Definition: Flag.h:20
@ OK
Definition: Flag.h:16
@ TIMEOUT
Definition: Flag.h:19
@ COMM_ERROR
Definition: Flag.h:17
Comm::Flag DoSelect(int)
Do poll and trigger callback functions as appropriate.
Definition: ModDevPoll.cc:311
void SelectLoopInit(void)
Initialize the module on Squid startup.
Definition: ModDevPoll.cc:176
void SetSelect(int, unsigned int, PF *, void *, time_t)
Mark an FD to be watched for its IO status.
Definition: ModDevPoll.cc:223
void RegisterAction(char const *action, char const *desc, OBJH *handler, int pw_req_flag, int atomic)
Definition: Registration.cc:16
static void handler(int signo)
Definition: purge.cc:854
static struct stat sb
Definition: squidclient.cc:71
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
Definition: store.cc:830
double current_dtime
the current UNIX time in seconds (with microsecond precision)
Definition: stub_libtime.cc:19
time_t getCurrentTime() STUB_RETVAL(0) int tvSubUsec(struct timeval
int nfds
Definition: tcp-banger2.c:129
int maxfd
Definition: tcp-banger2.c:130
unsigned long fd_mask
Definition: types.h:154
const char * xstrerr(int error)
Definition: xstrerror.cc:83

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors