diff -r -N -U 3 ./squid-3.0-DEVEL-20021126.orig/configure ./squid-3.0-DEVEL-20021126/configure --- ./squid-3.0-DEVEL-20021126.orig/configure Mon Nov 25 20:11:32 2002 +++ ./squid-3.0-DEVEL-20021126/configure Tue Dec 3 17:13:21 2002 @@ -899,6 +899,8 @@ --disable-select Disable select() support. --enable-kqueue Enable kqueue() support. --disable-kqueue Disable kqueue() support. + --enable-epoll Enable kqueue() support. + --disable-epoll Disable kqueue() support. --disable-http-violations This allows you to remove code which is known to violate the HTTP protocol specification. @@ -4718,6 +4720,26 @@ fi; +# Check whether --enable-epoll or --disable-epoll was given. +if test "${enable_epoll+set}" = set; then + enableval="$enable_epoll" + + case "$enableval" in + yes) + echo "Forcing epoll() to be enabled" + ac_cv_func_epoll='yes' + if test -z "$EPOLL_LIBS"; then + EPOLL_LIBS="-lepoll" + fi + ;; + no) + echo "Forcing epoll() to be disabled" + ac_cv_func_epoll='no' + ;; +esac + +fi; + http_violations=1 # Check whether --enable-http-violations or --disable-http-violations was given. if test "${enable_http_violations+set}" = set; then @@ -14656,8 +14678,15 @@ #define USE_KQUEUE 1 _ACEOF +elif test "$ac_cv_func_epoll" = "yes" ; then + SELECT_TYPE="epoll" + +cat >>confdefs.h <<\_ACEOF +#define USE_EPOLL 1 +_ACEOF + else - echo "Eep! Can't find poll, kqueue or select!" + echo "Eep! Can't find poll, kqueue, epoll or select!" echo "I'll try select and hope for the best." SELECT_TYPE="select" cat >>confdefs.h <<\_ACEOF @@ -16509,6 +16538,7 @@ s,@LIBOBJS@,$LIBOBJS,;t t s,@XTRA_OBJS@,$XTRA_OBJS,;t t s,@XTRA_LIBS@,$XTRA_LIBS,;t t +s,@EPOLL_LIBS@,$EPOLL_LIBS,;t t CEOF _ACEOF diff -r -N -U 3 ./squid-3.0-DEVEL-20021126.orig/configure.in ./squid-3.0-DEVEL-20021126/configure.in --- ./squid-3.0-DEVEL-20021126.orig/configure.in Mon Nov 25 20:11:32 2002 +++ ./squid-3.0-DEVEL-20021126/configure.in Tue Dec 3 17:13:00 2002 @@ -743,6 +743,28 @@ esac ]) +dnl Enable epoll() +AC_ARG_ENABLE(epoll, +[ --enable-epoll Enable epoll() support. + --disable-epoll Disable epoll() support. ], + +[ + case "$enableval" in + yes) + echo "Forcing epoll() to be enabled" + ac_cv_func_epoll='yes' + if test -z "$EPOLL_LIBS"; then + EPOLL_LIBS="-lepoll" + fi + AC_SUBST(EPOLL_LIBS) + ;; + no) + echo "Forcing epoll() to be disabled" + ac_cv_func_epoll='no' + ;; +esac +]) + dnl Disable HTTP violations http_violations=1 AC_ARG_ENABLE(http-violations, @@ -1800,8 +1822,11 @@ elif test "$ac_cv_func_kqueue" = "yes" ; then SELECT_TYPE="kqueue" AC_DEFINE(USE_KQUEUE,1,[Use kqueue() for the IO loop]) +elif test "$ac_cv_func_epoll" = "yes" ; then + SELECT_TYPE="epoll" + AC_DEFINE(USE_EPOLL,1,[Use epoll() for the IO loop]) else - echo "Eep! Can't find poll, kqueue or select!" + echo "Eep! Can't find poll, kqueue, epoll, or select!" echo "I'll try select and hope for the best." SELECT_TYPE="select" AC_DEFINE(USE_SELECT,1) diff -r -N -U 3 ./squid-3.0-DEVEL-20021126.orig/include/autoconf.h.in ./squid-3.0-DEVEL-20021126/include/autoconf.h.in --- ./squid-3.0-DEVEL-20021126.orig/include/autoconf.h.in Sun Oct 6 04:18:02 2002 +++ ./squid-3.0-DEVEL-20021126/include/autoconf.h.in Wed Nov 27 10:45:32 2002 @@ -746,6 +746,9 @@ /* Compile in support for Ident (RFC 931) lookups? Enabled by default. */ #undef USE_IDENT +/* Use epoll() for the IO loop */ +#undef USE_EPOLL + /* Use kqueue() for the IO loop */ #undef USE_KQUEUE diff -r -N -U 3 ./squid-3.0-DEVEL-20021126.orig/src/Makefile.am ./squid-3.0-DEVEL-20021126/src/Makefile.am --- ./squid-3.0-DEVEL-20021126.orig/src/Makefile.am Fri Nov 22 09:04:31 2002 +++ ./squid-3.0-DEVEL-20021126/src/Makefile.am Tue Dec 3 17:13:51 2002 @@ -6,6 +6,12 @@ # Uncomment and customize the following to suit your needs: # +if USE_EPOLL +EPOLL_LIBS = -lepoll +else +EPOLL_LIBS = +endif + if USE_DNSSERVER DNSSOURCE = dns.cc DNSSERVER = dnsserver @@ -140,6 +146,7 @@ comm_select.cc \ comm_poll.cc \ comm_kqueue.cc \ + comm_epoll.cc \ debug.cc \ defines.h \ $(DELAY_POOL_SOURCE) \ diff -r -N -U 3 ./squid-3.0-DEVEL-20021126.orig/src/Makefile.in ./squid-3.0-DEVEL-20021126/src/Makefile.in --- ./squid-3.0-DEVEL-20021126.orig/src/Makefile.in Fri Nov 22 09:25:38 2002 +++ ./squid-3.0-DEVEL-20021126/src/Makefile.in Tue Dec 3 17:14:28 2002 @@ -231,6 +231,7 @@ comm_select.cc \ comm_poll.cc \ comm_kqueue.cc \ + comm_epoll.cc \ debug.cc \ defines.h \ $(DELAY_POOL_SOURCE) \ @@ -351,7 +352,8 @@ @LIB_MALLOC@ \ @SSLLIB@ \ -lmiscutil \ - @XTRA_LIBS@ + @XTRA_LIBS@ \ + @EPOLL_LIBS@ squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a @@ -389,7 +391,7 @@ mib.txt -LDADD = -L../lib -lmiscutil @XTRA_LIBS@ +LDADD = -L../lib -lmiscutil @XTRA_LIBS@ @EPOLL_LIBS@ EXTRA_DIST = \ cf_gen_defines \ @@ -521,7 +523,7 @@ client_db.$(OBJEXT) client_side.$(OBJEXT) \ client_side_reply.$(OBJEXT) client_side_request.$(OBJEXT) \ clientStream.$(OBJEXT) comm.$(OBJEXT) comm_select.$(OBJEXT) \ - comm_poll.$(OBJEXT) comm_kqueue.$(OBJEXT) debug.$(OBJEXT) \ + comm_poll.$(OBJEXT) comm_kqueue.$(OBJEXT) comm_epoll.$(OBJEXT) debug.$(OBJEXT) \ $(am__objects_4) disk.$(OBJEXT) $(am__objects_5) \ errorpage.$(OBJEXT) ETag.$(OBJEXT) event.$(OBJEXT) \ external_acl.$(OBJEXT) fd.$(OBJEXT) filemap.$(OBJEXT) \ @@ -590,7 +592,7 @@ @AMDEP_TRUE@ $(DEPDIR)/client_side.Po \ @AMDEP_TRUE@ $(DEPDIR)/client_side_reply.Po \ @AMDEP_TRUE@ $(DEPDIR)/client_side_request.Po $(DEPDIR)/comm.Po \ -@AMDEP_TRUE@ $(DEPDIR)/comm_kqueue.Po $(DEPDIR)/comm_poll.Po \ +@AMDEP_TRUE@ $(DEPDIR)/comm_epoll.Po $(DEPDIR)/comm_kqueue.Po $(DEPDIR)/comm_poll.Po \ @AMDEP_TRUE@ $(DEPDIR)/comm_select.Po $(DEPDIR)/debug.Po \ @AMDEP_TRUE@ $(DEPDIR)/delay_pools.Po $(DEPDIR)/disk.Po \ @AMDEP_TRUE@ $(DEPDIR)/dns.Po $(DEPDIR)/dns_internal.Po \ @@ -809,6 +811,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/client_side_reply.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/client_side_request.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/comm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/comm_epoll.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/comm_kqueue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/comm_poll.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/comm_select.Po@am__quote@ diff -r -N -U 3 ./squid-3.0-DEVEL-20021126.orig/src/comm_epoll.cc ./squid-3.0-DEVEL-20021126/src/comm_epoll.cc --- ./squid-3.0-DEVEL-20021126.orig/src/comm_epoll.cc Wed Dec 31 19:00:00 1969 +++ ./squid-3.0-DEVEL-20021126/src/comm_epoll.cc Tue Dec 3 17:41:22 2002 @@ -0,0 +1,253 @@ + +/* + * $Id: comm_epoll.cc,v 0.1 2002/11/26 16:57:15 dnicklay Exp $ + * + * DEBUG: section 5 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. + * + */ + +/* + * XXX Currently not implemented / supported by this module XXX + * + * - delay pools + * - deferred reads + * + */ + +#include "squid.h" +#include "Store.h" + +#ifdef USE_EPOLL +#define DEBUG_EPOLL 1 + +#define __USE_XOPEN +#include +#undef __USE_XOPEN + +static int kdpfd; +static int max_poll_time = 1000; +static struct epoll_event *pevents; + + +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +/* Private functions */ + +void +ep_update_events(int fd, int events) +{ + struct epoll_event ev; + + ev.data.fd = fd; + if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, fd, &ev) < 0) { /* add the events */ + if(errno == EEXIST) { /* exists .. modify it instead .. */ + if (epoll_ctl(kdpfd, EPOLL_CTL_MOD, fd, &ev) < 0) { + debug(5,1) ("ep_update_events(): epoll_ctl(,EPOLL_CTL_MOD,,) failed"); + return; + } + } else { + debug(5,1) ("ep_update_events(): epoll_ctl(,EPOLL_CTL_ADD,,) failed"); + return; + } + } +} + + +void +ep_delete(int fd) +{ + struct epoll_event ev; + + ev.data.fd = fd; + if(epoll_ctl(kdpfd,EPOLL_CTL_DEL,fd,&ev) < 0) { + if(errno != ENOENT) { + debug(5,3) ("ep_delete: epoll_ctl() failed on fd=%d: entry does not exist\n",fd); + } else { + debug(5,1) ("ep_delete: cpoll_ctl() failed!: %s\n",xstrerror()); + } + } + return; +} + + +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +/* Public functions */ + + +/* + * comm_select_init + * + * This is a needed exported function which will be called to initialise + * the network loop code. + */ +void +comm_select_init(void) +{ + pevents = (struct epoll_event *) xmalloc(SQUID_MAXFD * sizeof(struct epoll_event)); + if (!pevents) { + fatalf("comm_select_init: xmalloc() failed: %s\n",xstrerror()); + } + kdpfd = epoll_create(SQUID_MAXFD); + if (kdpfd < 0) { + fatalf("comm_select_init: epoll_create(): %s\n",xstrerror()); + } +} + +/* + * comm_setselect + * + * This is a needed exported function which will be called to register + * and deregister interest in a pending IO state for a given FD. + * + * -- FIXME -- There is a strange problem in that snmp always returns that there are + * events ready, but when snmpHandleUdp is called on them you always get EAGAIN. + */ +void +commSetSelect(int fd, unsigned int type, PF * handler, + void *client_data, time_t timeout) +{ + fde *F = &fd_table[fd]; + int change = 0; + int events = 0; + int pollin = 0; + int pollout = 0; + assert(fd >= 0); + assert(F->flags.open); + /* There is a weird alignment bug somewhere, that this seems to fix.... --FIXME--*/ + debug(5, DEBUG_EPOLL ? 0 : 8) ("\n"); + debug(5, DEBUG_EPOLL ? 0 : 8) ("\n"); + debug(5, DEBUG_EPOLL ? 0 : 8) ("\n"); + debug(5, DEBUG_EPOLL ? 0 : 8) ("\n"); + debug(5, DEBUG_EPOLL ? 0 : 8) ("\n"); + debug(5, DEBUG_EPOLL ? 0 : 8) ("\n"); + debug(5, DEBUG_EPOLL ? 0 : 8) ("\n"); + /* -------------------------------------------------------------------- */ + if(F->read_handler != NULL) + pollin = 1; + if(F->write_handler != NULL) + pollout = 1; + if (type & COMM_SELECT_READ) { + if(F->read_handler != handler) + change = 1; + if(handler == NULL) + pollin = 0; + else + pollin = 1; + F->read_handler = handler; + F->read_data = client_data; + } + if (type & COMM_SELECT_WRITE) { + if(F->write_handler != handler) + change = 1; + if(handler == NULL) + pollout = 0; + else + pollout = 1; + F->write_handler = handler; + F->write_data = client_data; + } + if(pollin) + events |= EPOLLIN; + if(pollout) + events |= EPOLLOUT; + if(events) + events |= EPOLLHUP | EPOLLERR; + if(events) + ep_update_events(fd, events); + else if(change) + ep_delete(fd); + if (timeout) + F->timeout = squid_curtime + timeout; +} + +/* + * Check all connections for new connections and input data that is to be + * processed. Also check for connections with data queued and whether we can + * write it out. + */ + +/* + * comm_select + * + * Called to do the new-style IO, courtesy of of squid (like most of this + * new IO code). This routine handles the stuff we've hidden in + * comm_setselect and fd_table[] and calls callbacks for IO ready + * events. + */ + +comm_err_t +comm_select(int msec) +{ + int num, i,fd; + fde *F; + PF *hdl; + struct epoll_event *cevents; + + if (msec > max_poll_time) + msec = max_poll_time; + for (;;) { + num = epoll_wait(kdpfd, pevents, SQUID_MAXFD, msec); + statCounter.select_loops++; + if (num >= 0) + break; + if (ignoreErrno(errno)) + break; + getCurrentTime(); + return COMM_ERROR; + } + + getCurrentTime(); + if (num == 0) + return COMM_OK; /* No error.. */ + + for (i = 0, cevents = pevents; i < num; i++, cevents++) { + fd = cevents->data.fd; + F = &fd_table[fd]; + if(cevents->events & (EPOLLRDBAND|EPOLLRDNORM|EPOLLIN|EPOLLHUP|EPOLLERR)) { + if((hdl = F->read_handler) != NULL) { + F->read_handler = NULL; + hdl(fd, F->read_data); + } + } + if(cevents->events & (EPOLLWRBAND|EPOLLWRNORM|EPOLLOUT|EPOLLHUP|EPOLLERR)) { + if((hdl = F->write_handler) != NULL) { + F->write_handler = NULL; + hdl(fd, F->write_data); + } + } + } + return COMM_OK; +} + +void +comm_quick_poll_required(void) +{ + max_poll_time = 100; +} + +#endif /* USE_EPOLL */