35#define howmany(x, y) (((x)+((y)-1))/(y))
40#define FD_MASK_BYTES sizeof(fd_mask)
41#define FD_MASK_BITS (FD_MASK_BYTES*NBBY)
108#define MAX_INCOMING_INTEGER 256
109#define INCOMING_FACTOR 5
110#define MAX_INCOMING_INTERVAL (MAX_INCOMING_INTEGER << INCOMING_FACTOR)
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))
127 debugs(5, 5,
"FD " << fd <<
", type=" << type <<
128 ", handler=" <<
handler <<
", client_data=" << client_data <<
129 ", timeout=" << timeout);
133 F->read_data = client_data;
139 F->write_data = client_data;
175 if (s->listenConn !=
nullptr && s->listenConn->fd == fd)
192 FD_ZERO(&write_mask);
195 for (i = 0; i < nfds; ++i) {
199 FD_SET(fd, &read_mask);
206 FD_SET(fd, &write_mask);
220 if (select(maxfd, &read_mask, &write_mask,
nullptr, &
zero_tv) < 1)
223 for (i = 0; i < nfds; ++i) {
226 if (FD_ISSET(fd, &read_mask)) {
227 if ((hdl =
fd_table[fd].read_handler) !=
nullptr) {
228 fd_table[fd].read_handler =
nullptr;
236 if (FD_ISSET(fd, &write_mask)) {
237 if ((hdl =
fd_table[fd].write_handler) !=
nullptr) {
238 fd_table[fd].write_handler =
nullptr;
299 fds[nfds] = s->listenConn->fd;
332 int calldns = 0, calludp = 0, calltcp = 0;
340 struct timeval poll_time;
358 calldns = calludp = calltcp = 0;
371 FD_ZERO(&pendingfds);
377 for (j = 0; j < maxindex; ++j) {
378 if ((tmask = fdsp[j]) == 0)
388 if (FD_ISSET(fd, &readfds) &&
fd_table[fd].flags.read_pending) {
389 FD_SET(fd, &pendingfds);
407 poll_time.tv_sec = msec / 1000;
408 poll_time.tv_usec = (msec % 1000) * 1000;
410 num = select(maxfd, &readfds, &writefds,
nullptr, &poll_time);
414 if (num >= 0 || pending > 0)
429 if (num < 0 && !pending)
434 debugs(5, num ? 5 : 8,
"comm_select: " << num <<
"+" << pending <<
" FDs ready");
438 if (num == 0 && pending == 0)
444 pfdsp = (
fd_mask *) & pendingfds;
448 for (j = 0; j < maxindex; ++j) {
449 if ((tmask = (fdsp[j] | pfdsp[j])) == 0)
480 debugs(5, 6,
"comm_select: FD " << fd <<
" ready for reading");
482 if (
nullptr == (hdl =
F->read_handler))
485 F->read_handler =
nullptr;
487 hdl(fd,
F->read_data);
504 for (j = 0; j < maxindex; ++j) {
505 if ((tmask = fdsp[j]) == 0)
536 debugs(5, 6,
"comm_select: FD " << fd <<
" ready for writing");
538 if ((hdl =
F->write_handler)) {
539 F->write_handler =
nullptr;
541 hdl(fd,
F->write_data);
626 "comm_incoming() stats",
657 tv.tv_sec = tv.tv_usec = 0;
659 if (FD_ISSET(fd, readfds))
661 else if (FD_ISSET(fd, writefds))
662 FD_SET(fd, &write_x);
669 if (!fstat(fd, &
sb)) {
670 debugs(5, 5,
"FD " << fd <<
" is valid.");
679 debugs(5,
DBG_CRITICAL,
"tmout:" <<
F->timeoutHandler <<
" read:" <<
F->read_handler <<
" write:" <<
F->write_handler);
681 for (ch =
F->closeHandler; ch !=
nullptr; ch = ch->Next())
684 if (
F->closeHandler !=
nullptr) {
686 }
else if (
F->timeoutHandler !=
nullptr) {
691 F->closeHandler =
nullptr;
692 F->timeoutHandler =
nullptr;
693 F->read_handler =
nullptr;
694 F->write_handler =
nullptr;
696 FD_CLR(fd, writefds);
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");
#define ScheduleCallHere(call)
static fd_set global_readfds
static int fdIsTcpListener(int fd)
static int incoming_udp_interval
#define commCheckTcpIncoming
static int incoming_tcp_interval
static int fdIsDns(int fd)
static void commUpdateReadBits(int fd, PF *handler)
static void comm_select_udp_incoming(void)
static int incoming_dns_interval
#define commCheckDnsIncoming
#define commCheckUdpIncoming
static void comm_select_tcp_incoming(void)
static struct timeval zero_tv
static int examine_select(fd_set *, fd_set *)
static int fdIsUdpListener(int fd)
static int comm_check_incoming_select_handlers(int nfds, int *fds)
static OBJH commIncomingStats
#define MAX_INCOMING_INTERVAL
static void commUpdateWriteBits(int fd, PF *handler)
static fd_set global_writefds
static void comm_select_dns_incoming(void)
AnyP::PortCfgPointer HttpPortList
list of Squid http(s)_port configured
#define MAXTCPLISTENPORTS
StatHistBinDumper statHistIntDumper
struct SquidConfig::@112 comm_incoming
struct SquidConfig::@112::@119 udp
struct SquidConfig::@112::@119 tcp
struct SquidConfig::@112::@119 dns
struct StatCounters::@130 syscalls
StatHist comm_tcp_incoming
unsigned long int select_loops
StatHist comm_udp_incoming
StatHist comm_dns_incoming
void dump(StoreEntry *sentry, StatHistBinDumper *bd) const
void commCallCloseHandlers(int fd)
int ignoreErrno(int ierrno)
#define debugs(SECTION, LEVEL, CONTENT)
#define EBIT_CLR(flag, bit)
#define COMM_SELECT_WRITE
#define EBIT_TEST(flag, bit)
int incoming_sockets_accepted
Comm::ConnectionPointer icpOutgoingConn
Comm::ConnectionPointer icpIncomingConn
static uint32 F(uint32 X, uint32 Y, uint32 Z)
void QuickPollRequired(void)
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Comm::Flag DoSelect(int)
Do poll and trigger callback functions as appropriate.
void SelectLoopInit(void)
Initialize the module on Squid startup.
void SetSelect(int, unsigned int, PF *, void *, time_t)
Mark an FD to be watched for its IO status.
void RegisterAction(char const *action, char const *desc, OBJH *handler, int pw_req_flag, int atomic)
static void handler(int signo)
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
double current_dtime
the current UNIX time in seconds (with microsecond precision)
time_t getCurrentTime() STUB_RETVAL(0) int tvSubUsec(struct timeval
const char * xstrerr(int error)