From: wessels <> Date: Tue, 3 Dec 1996 07:46:02 +0000 (+0000) Subject: Hi Duane, X-Git-Tag: SQUID_3_0_PRE1~5354 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dcfe639004a3c1fc2e9f201de8ba6cd94bd37ec1;p=thirdparty%2Fsquid.git Hi Duane, Anthony Baxter and myself have completed the patches for comm.c to get it to use poll(2) directly rather than select(). This provides a largish performance increase for systems that implement select() as a library call (such as Solaris), and also allows systems such as Solaris to bypass the silly 1024 open FD limit which library select() has. We've tested this code on running systems and found a smallish increase in overall ability to service connections, and a respectable drop in CPU usage. To use, just compile with the -DUSE_POLL flag in the make options. Patch applies to 1.1b25 version of comm.c. As with all code, there probably are still bugs... --- diff --git a/ChangeLog b/ChangeLog index 00d36aeb80..a1400792eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ + - Another 'rm -rf' fix for store.c (Bernd Ernesti). + - Use of the Host: header for httpd_accel requests is now + disabled unless 'httpd_accel_uses_host_header' is set. + - Have configure check for libgnumalloc.a. + - Added support for using poll() instead of select() + (Stewart Forster, Anthony Baxter). + Changes to squid-1.1.beta25 (): - Check if we should delete-behind large objects when above LOW diff --git a/configure b/configure index 0e54e6d71f..31cf478bf6 100755 --- a/configure +++ b/configure @@ -514,7 +514,7 @@ fi -# From configure.in Revision: 1.55 +# From configure.in Revision: 1.56 ac_aux_dir= for ac_dir in aux $srcdir/aux; do if test -f $ac_dir/install-sh; then @@ -1437,6 +1437,7 @@ for ac_hdr in \ netdb.h \ netinet/in.h \ netinet/tcp.h \ + poll.h \ pwd.h \ regex.h \ resolv.h \ @@ -1471,12 +1472,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1480: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1481: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -1506,7 +1507,7 @@ if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1561: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -1578,7 +1579,7 @@ fi echo $ac_n "checking if ANSI prototypes work""... $ac_c" 1>&6 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1591: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_ANSI_PROTOTYPES 1 @@ -1602,7 +1603,7 @@ rm -f conftest* echo $ac_n "checking for tm->tm_gmtoff""... $ac_c" 1>&6 cat > conftest.$ac_ext < #include @@ -1612,7 +1613,7 @@ struct tm foo; foo.tm_gmtoff = 0; ; return 0; } EOF -if { (eval echo configure:1616: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1617: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_TM_GMTOFF 1 @@ -1628,7 +1629,7 @@ rm -f conftest* echo $ac_n "checking for extended mallinfo""... $ac_c" 1>&6 cat > conftest.$ac_ext < #include @@ -1638,7 +1639,7 @@ struct mallinfo foo; foo.mxfast = 0; ; return 0; } EOF -if { (eval echo configure:1642: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1643: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_EXT_MALLINFO 1 @@ -1654,7 +1655,7 @@ rm -f conftest* echo $ac_n "checking for ip->ip_hl""... $ac_c" 1>&6 cat > conftest.$ac_ext < #include @@ -1666,7 +1667,7 @@ struct ip ip; ip.ip_hl= 0; ; return 0; } EOF -if { (eval echo configure:1670: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1671: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_IP_HL 1 @@ -1688,7 +1689,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -1699,7 +1700,7 @@ main() exit(0); } EOF -{ (eval echo configure:1703: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } +{ (eval echo configure:1704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then ac_cv_sizeof_int=`cat conftestval` else @@ -1722,7 +1723,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -1733,7 +1734,7 @@ main() exit(0); } EOF -{ (eval echo configure:1737: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } +{ (eval echo configure:1738: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then ac_cv_sizeof_long=`cat conftestval` else @@ -1756,7 +1757,7 @@ if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return 0; } @@ -1764,7 +1765,7 @@ int t() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:1768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:1769: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -1788,7 +1789,7 @@ if eval "test \"`echo '$''{'ac_cv_func_alloca'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:1817: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* ac_cv_func_alloca=yes else @@ -1847,7 +1848,7 @@ if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:1905: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1932,7 +1933,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } +{ (eval echo configure:1956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then ac_cv_c_stack_direction=1 else @@ -1974,7 +1975,7 @@ if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2005,7 +2006,7 @@ if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2036,7 +2037,7 @@ if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2071,7 +2072,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2084: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2111,7 +2112,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2124: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2151,7 +2152,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgnumalloc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2164: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2200,7 +2201,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lmalloc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2213: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2243,7 +2244,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lbsd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2256: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2283,7 +2284,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lregex $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2296: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2317,7 +2318,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2334: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2350,7 +2351,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l44bsd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2367: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2398,7 +2399,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2439,7 +2440,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2456: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2479,7 +2480,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lshadow $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2492: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2521,7 +2522,7 @@ else ac_save_LIBS="$LIBS" LIBS="-labi $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2555,7 +2556,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lposix4 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -2642,6 +2643,7 @@ for ac_func in \ memcpy \ memmove \ mktime \ + poll \ pw_encrypt \ regcomp \ regexec \ @@ -2666,7 +2668,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2696: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2741,7 +2743,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:2771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2791,7 +2793,7 @@ if test "$cross_compiling" = yes; then SQUID_MAXFD=256 else cat > conftest.$ac_ext < @@ -2842,7 +2844,7 @@ main() { } EOF -{ (eval echo configure:2846: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } +{ (eval echo configure:2848: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then SQUID_MAXFD=`cat conftestval` else @@ -2861,7 +2863,7 @@ if test "$cross_compiling" = yes; then SQUID_UDP_SO_SNDBUF=16384 else cat > conftest.$ac_ext < @@ -2878,7 +2880,7 @@ main () } EOF -{ (eval echo configure:2882: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } +{ (eval echo configure:2884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then SQUID_UDP_SO_SNDBUF=`cat conftestval` else @@ -2897,7 +2899,7 @@ if test "$cross_compiling" = yes; then SQUID_UDP_SO_RCVBUF=16384 else cat > conftest.$ac_ext < @@ -2914,7 +2916,7 @@ main () } EOF -{ (eval echo configure:2918: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } +{ (eval echo configure:2920: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then SQUID_UDP_SO_RCVBUF=`cat conftestval` else @@ -2933,7 +2935,7 @@ if test "$cross_compiling" = yes; then SQUID_TCP_SO_SNDBUF=16384 else cat > conftest.$ac_ext < @@ -2950,7 +2952,7 @@ main () } EOF -{ (eval echo configure:2954: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } +{ (eval echo configure:2956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then SQUID_TCP_SO_SNDBUF=`cat conftestval` else @@ -2969,7 +2971,7 @@ if test "$cross_compiling" = yes; then SQUID_TCP_SO_RCVBUF=16384 else cat > conftest.$ac_ext < @@ -2986,7 +2988,7 @@ main () } EOF -{ (eval echo configure:2990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } +{ (eval echo configure:2992: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then SQUID_TCP_SO_RCVBUF=`cat conftestval` else @@ -3002,7 +3004,7 @@ EOF echo $ac_n "checking if sys_errlist is already defined""... $ac_c" 1>&6 cat > conftest.$ac_ext < int main() { return 0; } @@ -3010,7 +3012,7 @@ int t() { char *s = sys_errlist[0]; ; return 0; } EOF -if { (eval echo configure:3014: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3016: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 else @@ -3026,7 +3028,7 @@ rm -f conftest* echo $ac_n "checking for libresolv _dns_ttl_ hack""... $ac_c" 1>&6 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then +if { (eval echo configure:3040: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF diff --git a/configure.in b/configure.in index 9a65f90a21..97727e0089 100644 --- a/configure.in +++ b/configure.in @@ -3,13 +3,13 @@ dnl Configuration input file for Squid dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.56 1996/12/02 19:12:08 wessels Exp $ +dnl $Id: configure.in,v 1.57 1996/12/03 00:46:04 wessels Exp $ dnl dnl dnl AC_INIT(src/main.c) AC_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.56 $)dnl +AC_REVISION($Revision: 1.57 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AC_CONFIG_AUX_DIR(aux) @@ -136,6 +136,7 @@ AC_CHECK_HEADERS( \ netdb.h \ netinet/in.h \ netinet/tcp.h \ + poll.h \ pwd.h \ regex.h \ resolv.h \ @@ -308,6 +309,7 @@ AC_CHECK_FUNCS(\ memcpy \ memmove \ mktime \ + poll \ pw_encrypt \ regcomp \ regexec \ diff --git a/include/autoconf.h.in b/include/autoconf.h.in index 417091cd90..23421f969b 100644 --- a/include/autoconf.h.in +++ b/include/autoconf.h.in @@ -118,6 +118,9 @@ /* Define if you have the mktime function. */ #undef HAVE_MKTIME +/* Define if you have the poll function. */ +#undef HAVE_POLL + /* Define if you have the pw_encrypt function. */ #undef HAVE_PW_ENCRYPT @@ -229,6 +232,9 @@ /* Define if you have the header file. */ #undef HAVE_NETINET_TCP_H +/* Define if you have the header file. */ +#undef HAVE_POLL_H + /* Define if you have the header file. */ #undef HAVE_PWD_H diff --git a/src/Makefile.in b/src/Makefile.in index d8a4c80901..099334b866 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.58 1996/12/02 05:54:42 wessels Exp $ +# $Id: Makefile.in,v 1.59 1996/12/03 00:46:11 wessels Exp $ # # Uncomment and customize the following to suit your needs: # @@ -14,9 +14,10 @@ ICMP_OPT = # -DUSE_ICMP=1 DELAY_HACK = # -DDELAY_HACK=1 USERAGENT_OPT = # -DUSE_USERAGENT_LOG=1 KILL_PARENT_OPT = # -DKILL_PARENT_OPT -DEFINES = $(HOST_OPT) $(AIO_OPT) $(AUTH_OPT) $(LOG_HDRS_OPT) \ - $(ICMP_OPT) $(DELAY_HACK) $(USERAGENT_OPT) \ - $(KILL_PARENT_OPT) +USE_POLL_OPT = # -DUSE_POLL +DEFINES = $(HOST_OPT) $(AIO_OPT) $(AUTH_OPT) $(LOG_HDRS_OPT) \ + $(ICMP_OPT) $(DELAY_HACK) $(USERAGENT_OPT) \ + $(KILL_PARENT_OPT) $(USE_POLL_OPT) prefix = @prefix@ exec_prefix = @exec_prefix@ diff --git a/src/comm.cc b/src/comm.cc index 130978c4f5..6c02094587 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,6 +1,6 @@ /* - * $Id: comm.cc,v 1.113 1996/12/02 05:55:05 wessels Exp $ + * $Id: comm.cc,v 1.114 1996/12/03 00:46:12 wessels Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -137,7 +137,9 @@ FD_ENTRY *fd_table = NULL; /* also used in disk.c */ /* STATIC */ static int commBind _PARAMS((int s, struct in_addr, u_short port)); static int comm_cleanup_fd_entry _PARAMS((int)); +#ifndef USE_POLL static int examine_select _PARAMS((fd_set *, fd_set *)); +#endif static void checkTimeouts _PARAMS((void)); static void checkLifetimes _PARAMS((void)); static void Reserve_More_FDs _PARAMS((void)); @@ -608,6 +610,66 @@ comm_set_stall(int fd, int delta) fd_table[fd].stall_until = squid_curtime + delta; } + +#ifdef USE_POLL + +/* poll() version by: + * Stewart Forster , and + * Anthony Baxter */ + +static void +comm_select_incoming(void) +{ + int fd = 0; + int fds[3]; + struct pollfd pfds[3]; + int N = 0; + int i = 0; + PF hdl = NULL; + if (theInIcpConnection >= 0) + fds[N++] = theInIcpConnection; + if (theHttpConnection >= 0 && fdstat_are_n_free_fd(RESERVED_FD)) + fds[N++] = theHttpConnection; + fds[N++] = 0; + for (i = 0; i < N; i++) { + fd = fds[i]; + pfds[i].events = 0; + pfds[i].revents = 0; + pfds[i].fd = fd; + if (fd_table[fd].read_handler) { + pfds[i].events |= POLLRDNORM; + } + if (fd_table[fd].write_handler) { + pfds[i].events |= POLLWRNORM; + } + if (pfds[i].events == 0) + pfds[i].fd = -1; + } + pfds[N].fd = -1; /* just in case... */ + pfds[N].events = 0; + if (poll(pfds, N, (int) 0) < 1) + return; + getCurrentTime(); + for (i = 0; i < N; i++) { + if ((pfds[i].revents == 0) || (pfds[i].fd == -1)) + continue; + fd = fds[i]; + if (pfds[i].revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) { + hdl = fd_table[fd].read_handler; + fd_table[fd].read_handler = 0; + hdl(fd, fd_table[fd].read_data); + } + if (pfds[i].revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) { + hdl = fd_table[fd].write_handler; + fd_table[fd].write_handler = 0; + hdl(fd, fd_table[fd].write_data); + } + } + /* TO FIX: repoll ICP connection here */ +} + +#else + static void comm_select_incoming(void) { @@ -619,16 +681,13 @@ comm_select_incoming(void) int N = 0; int i = 0; PF hdl = NULL; - FD_ZERO(&read_mask); FD_ZERO(&write_mask); - if (theHttpConnection >= 0 && fdstat_are_n_free_fd(RESERVED_FD)) fds[N++] = theHttpConnection; if (theInIcpConnection >= 0) fds[N++] = theInIcpConnection; fds[N++] = 0; - for (i = 0; i < N; i++) { fd = fds[i]; if (fd_table[fd].read_handler) { @@ -642,27 +701,218 @@ comm_select_incoming(void) maxfd = fd; } } - if (maxfd++ == 0) return; - if (select(maxfd, &read_mask, &write_mask, NULL, &zero_tv) > 0) { - getCurrentTime(); - for (i = 0; i < N; i++) { - fd = fds[i]; - if (FD_ISSET(fd, &read_mask)) { - hdl = fd_table[fd].read_handler; - fd_table[fd].read_handler = 0; - hdl(fd, fd_table[fd].read_data); + if (select(maxfd, &read_mask, &write_mask, NULL, &zero_tv) < 1) + return; + getCurrentTime(); + for (i = 0; i < N; i++) { + fd = fds[i]; + if (FD_ISSET(fd, &read_mask)) { + hdl = fd_table[fd].read_handler; + fd_table[fd].read_handler = 0; + hdl(fd, fd_table[fd].read_data); + } + if (FD_ISSET(fd, &write_mask)) { + hdl = fd_table[fd].write_handler; + fd_table[fd].write_handler = 0; + hdl(fd, fd_table[fd].write_data); + } + } +} +#endif + + +#ifdef USE_POLL +/* poll all sockets; call handlers for those that are ready. */ +int +comm_select(time_t sec) +{ + struct pollfd pfds[FD_SETSIZE]; + PF hdl = NULL; + int fd; + int i; + int maxfd; + int nfds; + int incnfd; + int num; + int httpindex; + static time_t last_timeout = 0; + int poll_time = 0; + time_t timeout; + struct close_handler *ch = NULL; + struct close_handler *next = NULL; + FD_ENTRY *f = NULL; + /* assume all process are very fast (less than 1 second). Call + * time() only once */ + getCurrentTime(); + /* use only 1 second granularity */ + timeout = squid_curtime + sec; + do { + if (sec > 60) + fatal_dump(NULL); + if (shutdown_pending || reread_pending) { + serverConnectionsClose(); + ftpServerClose(); + dnsShutdownServers(); + redirectShutdownServers(); + if (shutdown_pending > 0) + setSocketShutdownLifetimes(Config.lifetimeShutdown); + else + setSocketShutdownLifetimes(0); + } + nfds = 0; + maxfd = fdstat_biggest_fd() + 1; + httpindex = -1; + for (i = 0; i < maxfd; i++) { + pfds[nfds].fd = -1; + pfds[nfds].events = 0; +#if USE_ASYNC_IO + /* Using async IO for disk handle, so don't select on them */ + if (fdstatGetType(i) == FD_FILE) + continue; +#endif + /* Check each open socket for a handler. */ + incnfd = 0; + if (fd_table[i].read_handler && fd_table[i].stall_until <= squid_curtime) { + pfds[nfds].events |= POLLRDNORM; + pfds[nfds].fd = i; + incnfd = 1; } - if (FD_ISSET(fd, &write_mask)) { - hdl = fd_table[fd].write_handler; - fd_table[fd].write_handler = 0; - hdl(fd, fd_table[fd].write_data); + if (fd_table[i].write_handler) { + pfds[nfds].events |= POLLWRNORM; + pfds[nfds].fd = i; + incnfd = 1; + } + if (incnfd == 1) { + if (i == theHttpConnection) + httpindex = nfds; + nfds++; } } - } + /* If we're out of free fd's, don't poll the http incoming fd */ + if (!fdstat_are_n_free_fd(RESERVED_FD) && httpindex >= 0) { + pfds[httpindex].fd = -1; + pfds[httpindex].events = 0; + } + pfds[nfds].fd = -1; /* just in case */ + pfds[nfds].events = 0; + if (shutdown_pending || reread_pending) + debug(5, 2, "comm_select: Still waiting on %d FDs\n", nfds); + if (nfds == 0) + return COMM_SHUTDOWN; + for (;;) { +#if USE_ASYNC_IO + /* Another CPU vs latency tradeoff for async IO */ + poll_time = 250; +#else + poll_time = sec > 0 ? 1000 : 0; +#endif + num = poll(pfds, nfds, poll_time); + getCurrentTime(); + if (num >= 0) + break; + if (errno == EINTR) + break; + debug(5, 0, "comm_select: poll failure: %s\n", + xstrerror()); + if (errno == EINVAL) { + /* nfds greater than OPEN_MAX?? How possible? Time */ + /* to bail - write out nfds to cache.log and start */ + /* emergency shutdown by sending SIGTERM to self */ + debug(20, 1, " Poll died with EINVAL. Tried to poll %d FD's\n", nfds); + kill(getpid(), SIGTERM); + } + /* examine_select is handled below and efficiently too */ + /*examine_select(&readfds, &writefds); XXXXX TO FIX */ + return COMM_ERROR; + /* NOTREACHED */ + } +#if USE_ASYNC_IO + aioExamine(); /* See if any IO completed */ +#endif + if (num < 0) + continue; /* redo the top loop */ + debug(5, num ? 5 : 8, "comm_select: %d sockets ready at %d\n", + num, (int) squid_curtime); + /* Check lifetime and timeout handlers ONCE each second. + * Replaces brain-dead check every time through the loop! */ + if (squid_curtime > last_timeout) { + last_timeout = squid_curtime; + checkTimeouts(); + checkLifetimes(); + } + if (num == 0) + continue; + /* scan each socket but the accept socket. Poll this + * more frequently to minimiize losses due to the 5 connect + * limit in SunOS */ + for (i = 0; i < nfds; i++) { + fd = pfds[i].fd; + if ((fd == -1) || (pfds[i].revents == 0)) + continue; + /* + * Admit more connections quickly until we hit the hard limit. + * Don't forget to keep the UDP acks coming and going. + */ + comm_select_incoming(); + if ((fd == theInIcpConnection) || (fd == theHttpConnection)) + continue; + if (pfds[i].revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) { + debug(5, 6, "comm_select: FD %d ready for reading\n", fd); + if (fd_table[fd].read_handler) { + hdl = fd_table[fd].read_handler; + fd_table[fd].read_handler = 0; + hdl(fd, fd_table[fd].read_data); + } + } + if (pfds[i].revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) { + debug(5, 5, "comm_select: FD %d ready for writing\n", fd); + if (fd_table[fd].write_handler) { + hdl = fd_table[fd].write_handler; + fd_table[fd].write_handler = 0; + hdl(fd, fd_table[fd].write_data); + } + } + if (pfds[i].revents & POLLNVAL) { + f = &fd_table[fd]; + debug(5, 0, "WARNING: FD %d has handlers, but it's invalid.\n", fd); + debug(5, 0, "FD %d is a %s\n", fd, fdstatTypeStr[fdstatGetType(fd)]); + debug(5, 0, "--> %s\n", fd_note(fd, NULL)); + debug(5, 0, "lifetm:%p tmout:%p read:%p write:%p\n", + f->lifetime_handler, + f->timeout_handler, + f->read_handler, + f->write_handler); + for (ch = f->close_handler; ch; ch = ch->next) + debug(5, 0, " close handler: %p\n", ch->handler); + if (f->close_handler) { + for (ch = f->close_handler; ch; ch = next) { + next = ch->next; + ch->handler(fd, ch->data); + safe_free(ch); + } + } else if (f->lifetime_handler) { + debug(5, 0, "examine_select: Calling Lifetime Handler\n"); + f->lifetime_handler(fd, f->lifetime_data); + } else if (f->timeout_handler) { + debug(5, 0, "examine_select: Calling Timeout Handler\n"); + f->timeout_handler(fd, f->timeout_data); + } + f->close_handler = NULL; + f->lifetime_handler = NULL; + f->timeout_handler = NULL; + f->read_handler = NULL; + f->write_handler = NULL; + } + } + return COMM_OK; + } while (timeout > getCurrentTime()); + debug(5, 8, "comm_select: time out: %d.\n", squid_curtime); + return COMM_TIMEOUT; } +#else /* Select on all sockets; call handlers for those that are ready. */ int @@ -806,6 +1056,7 @@ comm_select(time_t sec) debug(5, 8, "comm_select: time out: %d.\n", squid_curtime); return COMM_TIMEOUT; } +#endif void commSetSelect(int fd, unsigned int type, PF handler, void *client_data, time_t timeout) @@ -1026,6 +1277,7 @@ comm_init(void) } +#ifndef USE_POLL /* * examine_select - debug routine. * @@ -1098,6 +1350,7 @@ examine_select(fd_set * readfds, fd_set * writefds) } return 0; } +#endif char * fd_note(int fd, const char *s) diff --git a/src/squid.h b/src/squid.h index 8787cafeac..a92085b7d1 100644 --- a/src/squid.h +++ b/src/squid.h @@ -1,6 +1,6 @@ /* - * $Id: squid.h,v 1.80 1996/12/02 07:06:56 wessels Exp $ + * $Id: squid.h,v 1.81 1996/12/03 00:46:13 wessels Exp $ * * AUTHOR: Duane Wessels * @@ -163,6 +163,14 @@ #include #endif +#if defined(USE_POLL) && HAVE_POLL +#if HAVE_POLL_H +#include +#endif /* HAVE_POLL_H */ +#else +#undef USE_POLL +#endif + #ifdef __STDC__ #include #else