/*
- * $Id$
- *
- * DEBUG: section 05 Socket Functions
- *
- * SQUID Web Proxy Cache http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from
- * the Internet community; see the CONTRIBUTORS file for full
- * details. Many organizations have provided support for Squid's
- * development; see the SPONSORS file for full details. Squid is
- * Copyrighted (C) 2001 by the Regents of the University of
- * California; see the COPYRIGHT file for full details. Squid
- * incorporates software developed and/or copyrighted by other
- * sources; see the CREDITS file for full details.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
*
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
*/
+
+/* DEBUG: section 05 Socket Functions */
+
#include "squid.h"
#if USE_POLL
-
-#include "squid-old.h"
#include "anyp/PortCfg.h"
#include "comm/Connection.h"
#include "comm/Loops.h"
+#include "fd.h"
#include "fde.h"
+#include "globals.h"
#include "ICP.h"
#include "mgr/Registration.h"
+#include "profiler/Profiler.h"
+#include "SquidConfig.h"
#include "SquidTime.h"
#include "StatCounters.h"
#include "Store.h"
+#include <cerrno>
#if HAVE_POLL_H
#include <poll.h>
#endif
#endif
#endif
-static int MAX_POLL_TIME = 1000; /* see also Comm::QuickPollRequired() */
+static int MAX_POLL_TIME = 1000; /* see also Comm::QuickPollRequired() */
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y))
#define commCheckDnsIncoming (++dns_io_events > (incoming_dns_interval>> INCOMING_FACTOR))
#define commCheckTcpIncoming (++tcp_io_events > (incoming_tcp_interval>> INCOMING_FACTOR))
-
void
Comm::SetSelect(int fd, unsigned int type, PF * handler, void *client_data, time_t timeout)
{
static int
fdIsTcpListen(int fd)
{
- for (const AnyP::PortCfg *s = Config.Sockaddr.http; s; s = s->next) {
+ for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) {
if (s->listenConn != NULL && s->listenConn->fd == fd)
return 1;
}
PROF_start(comm_check_incoming);
incoming_sockets_accepted = 0;
- for (i = npfds = 0; i < nfds; i++) {
+ for (i = npfds = 0; i < nfds; ++i) {
int events;
fd = fds[i];
events = 0;
pfds[npfds].fd = fd;
pfds[npfds].events = events;
pfds[npfds].revents = 0;
- npfds++;
+ ++npfds;
}
}
}
getCurrentTime();
- statCounter.syscalls.selects++;
+ ++ statCounter.syscalls.selects;
if (poll(pfds, npfds, 0) < 1) {
PROF_stop(comm_check_incoming);
return incoming_sockets_accepted;
}
- for (i = 0; i < npfds; i++) {
+ for (i = 0; i < npfds; ++i) {
int revents;
if (((revents = pfds[i].revents) == 0) || ((fd = pfds[i].fd) == -1))
fd_table[fd].read_handler = NULL;
hdl(fd, fd_table[fd].read_data);
} else if (pfds[i].events & POLLRDNORM)
- debugs(5, 1, "comm_poll_incoming: FD " << fd << " NULL read handler");
+ debugs(5, DBG_IMPORTANT, "comm_poll_incoming: FD " << fd << " NULL read handler");
}
if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) {
fd_table[fd].write_handler = NULL;
hdl(fd, fd_table[fd].write_data);
} else if (pfds[i].events & POLLWRNORM)
- debugs(5, 1, "comm_poll_incoming: FD " << fd << " NULL write_handler");
+ debugs(5, DBG_IMPORTANT, "comm_poll_incoming: FD " << fd << " NULL write_handler");
}
}
int nevents;
udp_io_events = 0;
- if (Comm::IsConnOpen(icpIncomingConn))
- fds[nfds++] = icpIncomingConn->fd;
+ if (Comm::IsConnOpen(icpIncomingConn)) {
+ fds[nfds] = icpIncomingConn->fd;
+ ++nfds;
+ }
- if (icpIncomingConn != icpOutgoingConn && Comm::IsConnOpen(icpOutgoingConn))
- fds[nfds++] = icpOutgoingConn->fd;
+ if (icpIncomingConn != icpOutgoingConn && Comm::IsConnOpen(icpOutgoingConn)) {
+ fds[nfds] = icpOutgoingConn->fd;
+ ++nfds;
+ }
if (nfds == 0)
return;
// XXX: only poll sockets that won't be deferred. But how do we identify them?
- for (j = 0; j < NHttpSockets; j++) {
+ for (j = 0; j < NHttpSockets; ++j) {
if (HttpSockets[j] < 0)
continue;
- fds[nfds++] = HttpSockets[j];
+ fds[nfds] = HttpSockets[j];
+ ++nfds;
}
nevents = comm_check_incoming_poll_handlers(nfds, fds);
}
/* poll all sockets; call handlers for those that are ready. */
-comm_err_t
+Comm::Flag
Comm::DoSelect(int msec)
{
struct pollfd pfds[SQUID_MAXFD];
maxfd = Biggest_FD + 1;
- for (int i = 0; i < maxfd; i++) {
+ for (int i = 0; i < maxfd; ++i) {
int events;
events = 0;
/* Check each open socket for a handler. */
pfds[nfds].fd = i;
pfds[nfds].events = events;
pfds[nfds].revents = 0;
- nfds++;
+ ++nfds;
if ((events & POLLRDNORM) && fd_table[i].flags.read_pending)
- npending++;
+ ++npending;
}
}
*/
if (nfds == 0 && npending == 0) {
if (shutting_down)
- return COMM_SHUTDOWN;
+ return Comm::SHUTDOWN;
else
- return COMM_IDLE;
+ return Comm::IDLE;
}
for (;;) {
PROF_start(comm_poll_normal);
- ++statCounter.syscalls.selects;
+ ++ statCounter.syscalls.selects;
num = poll(pfds, nfds, msec);
- ++statCounter.select_loops;
+ int xerrno = errno;
+ ++ statCounter.select_loops;
PROF_stop(comm_poll_normal);
if (num >= 0 || npending > 0)
break;
- if (ignoreErrno(errno))
+ if (ignoreErrno(xerrno))
continue;
- debugs(5, 0, "comm_poll: poll failure: " << xstrerror());
+ debugs(5, DBG_CRITICAL, MYNAME << "poll failure: " << xstrerr(xerrno));
- assert(errno != EINVAL);
+ assert(xerrno != EINVAL);
- return COMM_ERROR;
+ return Comm::COMM_ERROR;
/* NOTREACHED */
}
* limit in SunOS */
PROF_start(comm_handle_ready_fd);
- for (size_t loopIndex = 0; loopIndex < nfds; loopIndex++) {
+ for (size_t loopIndex = 0; loopIndex < nfds; ++loopIndex) {
fde *F;
int revents = pfds[loopIndex].revents;
fd = pfds[loopIndex].fd;
if ((hdl = F->read_handler)) {
PROF_start(comm_read_handler);
F->read_handler = NULL;
- F->flags.read_pending = 0;
+ F->flags.read_pending = false;
hdl(fd, F->read_data);
PROF_stop(comm_read_handler);
- statCounter.select_fds++;
+ ++ statCounter.select_fds;
if (commCheckUdpIncoming)
comm_poll_udp_incoming();
F->write_handler = NULL;
hdl(fd, F->write_data);
PROF_stop(comm_write_handler);
- statCounter.select_fds++;
+ ++ statCounter.select_fds;
if (commCheckUdpIncoming)
comm_poll_udp_incoming();
if (revents & POLLNVAL) {
AsyncCall::Pointer ch;
- debugs(5, 0, "WARNING: FD " << fd << " has handlers, but it's invalid.");
- debugs(5, 0, "FD " << fd << " is a " << fdTypeStr[F->type]);
- debugs(5, 0, "--> " << F->desc);
- debugs(5, 0, "tmout:" << F->timeoutHandler << "read:" <<
+ debugs(5, DBG_CRITICAL, "WARNING: FD " << fd << " has handlers, but it's invalid.");
+ debugs(5, DBG_CRITICAL, "FD " << fd << " is a " << fdTypeStr[F->type]);
+ debugs(5, DBG_CRITICAL, "--> " << F->desc);
+ debugs(5, DBG_CRITICAL, "tmout:" << F->timeoutHandler << "read:" <<
F->read_handler << " write:" << F->write_handler);
for (ch = F->closeHandler; ch != NULL; ch = ch->Next())
- debugs(5, 0, " close handler: " << ch);
+ debugs(5, DBG_CRITICAL, " close handler: " << ch);
if (F->closeHandler != NULL) {
commCallCloseHandlers(fd);
} else if (F->timeoutHandler != NULL) {
- debugs(5, 0, "comm_poll: Calling Timeout Handler");
+ debugs(5, DBG_CRITICAL, "comm_poll: Calling Timeout Handler");
ScheduleCallHere(F->timeoutHandler);
}
statCounter.select_time += (current_dtime - start);
- return COMM_OK;
+ return Comm::OK;
} while (timeout > current_dtime);
debugs(5, 8, "comm_poll: time out: " << squid_curtime << ".");
- return COMM_TIMEOUT;
+ return Comm::TIMEOUT;
}
-
static void
comm_poll_dns_incoming(void)
{
if (DnsSocketA < 0 && DnsSocketB < 0)
return;
- if (DnsSocketA >= 0)
- fds[nfds++] = DnsSocketA;
+ if (DnsSocketA >= 0) {
+ fds[nfds] = DnsSocketA;
+ ++nfds;
+ }
- if (DnsSocketB >= 0)
- fds[nfds++] = DnsSocketB;
+ if (DnsSocketB >= 0) {
+ fds[nfds] = DnsSocketB;
+ ++nfds;
+ }
nevents = comm_check_incoming_poll_handlers(nfds, fds);
statCounter.comm_dns_incoming.count(nevents);
}
-
static void
commPollRegisterWithCacheManager(void)
{
}
#endif /* USE_POLL */
+