--------------------- PatchSet 949 Date: 2000/12/17 14:09:08 Author: hno Branch: tcp_async Tag: Z-raid_merge_tcp_async Log: Imported tcp_async from squidng Members: acconfig.h:1.4.6.1->1.4.6.1.2.1 configure.in:1.7.6.1->1.7.6.1.2.1 doc/debug-sections.txt:1.2.22.1->1.2.22.1.2.1 src/Makefile.in:1.3->1.3.22.1 src/client_side.c:1.10.2.1->1.10.2.1.4.1 src/comm.c:1.4.14.1->1.4.14.1.4.1 src/comm_cio.c:1.1->1.1.2.1 src/comm_select.c:1.3->1.3.22.1 src/debug.c:1.3->1.3.22.1 src/disk.c:1.4->1.4.20.1 src/fd.c:1.4->1.4.10.1 src/forward.c:1.5.4.1.2.1->1.5.4.1.2.1.2.1 src/ftp.c:1.5.10.1->1.5.10.1.4.1 src/gopher.c:1.5.4.1->1.5.4.1.4.1 src/http.c:1.5.10.1->1.5.10.1.4.1 src/main.c:1.6.4.1->1.6.4.1.4.1 src/protos.h:1.6.4.1.2.1->1.6.4.1.2.1.2.1 src/pump.c:1.4.14.1->1.4.14.1.4.1 src/squid.h:1.3.16.1.2.1->1.3.16.1.2.1.2.1 src/ssl.c:1.3.16.1->1.3.16.1.4.1 src/stat.c:1.4.14.1.2.1->1.4.14.1.2.1.2.1 src/structs.h:1.8.8.1->1.8.8.1.2.1 src/typedefs.h:1.4.10.1.2.1->1.4.10.1.2.1.2.1 src/wais.c:1.3.16.1->1.3.16.1.4.1 src/whois.c:1.3.16.1->1.3.16.1.4.1 src/fs/butterfly/store_dir_bf.c:1.1.2.1->1.1.2.1.2.1 Index: squid/acconfig.h =================================================================== RCS file: /cvsroot/squid-sf//squid/Attic/acconfig.h,v retrieving revision 1.4.6.1 retrieving revision 1.4.6.1.2.1 diff -u -r1.4.6.1 -r1.4.6.1.2.1 --- squid/acconfig.h 17 Dec 2000 13:55:39 -0000 1.4.6.1 +++ squid/acconfig.h 17 Dec 2000 14:09:08 -0000 1.4.6.1.2.1 @@ -20,7 +20,7 @@ * */ @ TOP @ -/* $Id: acconfig.h,v 1.4.6.1 2000/12/17 13:55:39 hno Exp $ */ +/* $Id: acconfig.h,v 1.4.6.1.2.1 2000/12/17 14:09:08 hno Exp $ */ /********************************* * START OF CONFIGURABLE OPTIONS * @@ -283,6 +283,13 @@ /* Print stacktraces on fatal errors */ #undef PRINT_STACK_TRACE +/* Signal driven async network IO */ +#undef TCP_ASYNC + +/* Periodically dump profile snapshots from running squid */ +#undef PROFILE_SQUID +#undef PROFIL_DELAY + /* * Define this if unlinkd is required * (strongly recommended for ufs storage type) Index: squid/configure.in =================================================================== RCS file: /cvsroot/squid-sf//squid/configure.in,v retrieving revision 1.7.6.1 retrieving revision 1.7.6.1.2.1 diff -u -r1.7.6.1 -r1.7.6.1.2.1 --- squid/configure.in 17 Dec 2000 13:55:39 -0000 1.7.6.1 +++ squid/configure.in 17 Dec 2000 14:09:08 -0000 1.7.6.1.2.1 @@ -3,13 +3,13 @@ dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.7.6.1 2000/12/17 13:55:39 hno Exp $ +dnl $Id: configure.in,v 1.7.6.1.2.1 2000/12/17 14:09:08 hno Exp $ dnl dnl dnl AC_INIT(src/main.c) AC_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.7.6.1 $)dnl +AC_REVISION($Revision: 1.7.6.1.2.1 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AC_CONFIG_AUX_DIR(cfgaux) @@ -745,6 +745,45 @@ fi ]) +dnl Enable signal driven async network IO +AC_ARG_ENABLE(ciociosan, +[ --enable-ciociosan Enable signal driven async network IO (requires butterfly)], +[ if test "$enableval" = "yes" ; then + echo "Enabling signal driven async network IO" + AC_DEFINE(TCP_ASYNC) + fi +]) + +dnl Enable gmon-based profiling +AC_ARG_ENABLE(profiling, +[ --enable-profiling Enable gmon-based profiling], +[ if test "$enableval" = "yes" ; then + echo "Enabling gmon-based profiling" + AC_DEFINE(PROFILE_SQUID) + if test "$GCC" = "yes"; then + CFLAGS="$CFLAGS -pg" + else + CFLAGS="$CFLAGS -p" + fi + fi +]) + +AC_ARG_ENABLE(profiling-delay, +[ --enable-profiling-delay=\"delay in seconds\" Delay between dumping profiling snapshots], +[ case $enableval in + yes) + PROFILE_DELAY=3600 + ;; + no) + ;; + *) + PROFILE_DELAY=$enableval + ;; + esac +]) +echo "Profiling snapshot dumping interval is set to " $PROFILE_DELAY +AC_DEFINE_UNQUOTED(PROFIL_DELAY,$PROFILE_DELAY) + # Force some compilers to use ANSI features # case "$host" in Index: squid/doc/debug-sections.txt =================================================================== RCS file: /cvsroot/squid-sf//squid/doc/debug-sections.txt,v retrieving revision 1.2.22.1 retrieving revision 1.2.22.1.2.1 diff -u -r1.2.22.1 -r1.2.22.1.2.1 --- squid/doc/debug-sections.txt 17 Dec 2000 13:55:39 -0000 1.2.22.1 +++ squid/doc/debug-sections.txt 17 Dec 2000 14:09:08 -0000 1.2.22.1.2.1 @@ -89,3 +89,4 @@ section 86 Store Directory, Balanced tree (Reiserfs) version section 88 Storage Manager TREE Interface I/O Routines, async section 89 Storage Manager TREE Interface I/O Routines +section 90 Signal-driven netword IO Index: squid/src/Makefile.in =================================================================== RCS file: /cvsroot/squid-sf//squid/src/Attic/Makefile.in,v retrieving revision 1.3 retrieving revision 1.3.22.1 diff -u -r1.3 -r1.3.22.1 --- squid/src/Makefile.in 23 Oct 2000 15:04:19 -0000 1.3 +++ squid/src/Makefile.in 17 Dec 2000 14:09:08 -0000 1.3.22.1 @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.3 2000/10/23 15:04:19 hno Exp $ +# $Id: Makefile.in,v 1.3.22.1 2000/12/17 14:09:08 hno Exp $ # # Uncomment and customize the following to suit your needs: # @@ -99,6 +99,7 @@ client_db.o \ client_side.o \ comm.o \ + comm_cio.o \ comm_select.o \ debug.o \ @DELAY_OBJS@ \ Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.10.2.1 retrieving revision 1.10.2.1.4.1 diff -u -r1.10.2.1 -r1.10.2.1.4.1 --- squid/src/client_side.c 17 Dec 2000 08:20:04 -0000 1.10.2.1 +++ squid/src/client_side.c 17 Dec 2000 14:09:08 -0000 1.10.2.1.4.1 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.10.2.1 2000/12/17 08:20:04 hno Exp $ + * $Id: client_side.c,v 1.10.2.1.4.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -2534,6 +2534,7 @@ if (size > 0) { fd_bytes(fd, size, FD_READ); kb_incr(&statCounter.client_http.kbytes_in, size); + CLEAR_CAN_READ_IF_EMPTY( len, size, fd ); } /* * Don't reset the timeout value here. The timeout value will be @@ -2565,9 +2566,12 @@ debug(50, 2) ("clientReadRequest: FD %d: %s\n", fd, xstrerror()); comm_close(fd); return; - } else if (conn->in.offset == 0) { + } else { + CLEAR_CAN_READ( fd ); + if (conn->in.offset == 0) { debug(50, 2) ("clientReadRequest: FD %d: no data to process (%s)\n", fd, xstrerror()); return; + } } /* Continue to process previously read data */ size = 0; Index: squid/src/comm.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/comm.c,v retrieving revision 1.4.14.1 retrieving revision 1.4.14.1.4.1 diff -u -r1.4.14.1 -r1.4.14.1.4.1 --- squid/src/comm.c 17 Dec 2000 08:20:04 -0000 1.4.14.1 +++ squid/src/comm.c 17 Dec 2000 14:09:08 -0000 1.4.14.1.4.1 @@ -1,6 +1,6 @@ /* - * $Id: comm.c,v 1.4.14.1 2000/12/17 08:20:04 hno Exp $ + * $Id: comm.c,v 1.4.14.1.4.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -61,6 +61,9 @@ #ifdef TCP_NODELAY static void commSetTcpNoDelay(int); #endif +#if defined( TCP_ASYNC ) +static void commSetTcpAsync(int); +#endif static void commSetTcpRcvbuf(int, int); static PF commConnectFree; static PF commConnectHandle; @@ -202,8 +205,17 @@ if (sock_type == SOCK_STREAM) commSetTcpNoDelay(new_socket); #endif +#ifdef TCP_ASYNC + if (sock_type == SOCK_STREAM) + { + /* this should be called after commSetNonBlocking, as + it resets descriptor's flags */ + commSetTcpAsync(new_socket); + } +#endif if (Config.tcpRcvBufsz > 0 && sock_type == SOCK_STREAM) commSetTcpRcvbuf(new_socket, Config.tcpRcvBufsz); + checkAsyncFlag( new_socket ); return new_socket; } @@ -459,7 +471,11 @@ if (errno == 0 || errno == EISCONN) status = COMM_OK; else if (ignoreErrno(errno)) + { status = COMM_INPROGRESS; + CLEAR_CAN_WRITE( sock ); + CLEAR_CAN_READ( sock ); + } else return COMM_ERROR; xstrncpy(F->ipaddr, inet_ntoa(address->sin_addr), 16); @@ -488,6 +504,7 @@ if ((sock = accept(fd, (struct sockaddr *) &P, &Slen)) < 0) { if (ignoreErrno(errno)) { debug(50, 5) ("comm_accept: FD %d: %s\n", fd, xstrerror()); + CLEAR_CAN_READ( fd ); return COMM_NOMESSAGE; } else if (ENFILE == errno || EMFILE == errno) { debug(50, 3) ("comm_accept: FD %d: %s\n", fd, xstrerror()); @@ -512,6 +529,9 @@ F->remote_port = htons(P.sin_port); F->local_port = htons(M.sin_port); commSetNonBlocking(sock); +#if defined( TCP_ASYNC ) + commSetTcpAsync( sock ); +#endif return sock; } @@ -780,6 +800,45 @@ } #endif +#ifdef TCP_ASYNC + +static pid_t our_pid = -1; + +/* XXX this uses Linux-specific hacks anyway */ +static void +commSetTcpAsync(int fd) +{ + if( fcntl( fd, F_SETFL, O_ASYNC | O_NONBLOCK ) == -1 ) + { + debug(50, 1) ("commSetTcpAsync: " + "fcntl( F_SETFL, O_ASYNC | O_NONBLOCK ): FD %d: %s\n", + fd, xstrerror()); + } + else if( fcntl( fd, F_SETSIG, SIGCIOCIOSAN ) == -1 ) + { + debug(50, 1) ("commSetTcpAsync: " + "fcntl( F_SETSIG ): FD %d: %s\n", + fd, xstrerror()); + } + else if( fcntl( fd, F_SETOWN, our_pid ) == -1 ) + { + debug(50, 1) ("commSetTcpAsync: " + "fcntl( F_SETOWN ): FD %d: %s\n", + fd, xstrerror()); + } + else + { + debug(50, 9) ("commSetTcpAsync: ok: fd: %i\n", fd ); + fd_table[ fd ].flags.async_tcp = 1; + fd_table[ fd ].flags.can_read = 1; + fd_table[ fd ].flags.can_write = 1; + } +} + +/* TCP_ASYNC */ +#endif + + void comm_init(void) @@ -791,6 +850,9 @@ * Since Squid_MaxFD can be as high as several thousand, don't waste them */ RESERVED_FD = XMIN(100, Squid_MaxFD / 4); CBDATA_INIT_TYPE(ConnectStateData); +#ifdef TCP_ASYNC + our_pid = getpid(); +#endif comm_write_pool = memPoolCreate("CommWriteStateData", sizeof(CommWriteStateData)); conn_close_pool = memPoolCreate("close_handler", sizeof(close_handler)); } @@ -803,6 +865,7 @@ int len = 0; int nleft; + checkAsyncFlag( fd ); debug(5, 5) ("commHandleWrite: FD %d: off %d, sz %d.\n", fd, (int) state->offset, state->size); @@ -827,6 +890,7 @@ } else if (ignoreErrno(errno)) { debug(50, 10) ("commHandleWrite: FD %d: write failure: %s.\n", fd, xstrerror()); + CLEAR_CAN_WRITE( fd ); commSetSelect(fd, COMM_SELECT_WRITE, commHandleWrite, @@ -838,6 +902,7 @@ CommWriteStateCallbackAndFree(fd, COMM_ERROR); } } else { + CLEAR_CAN_WRITE_IF_FULL( nleft, len, fd ); /* A successful write, continue */ state->offset += len; if (state->offset < state->size) { @@ -868,6 +933,7 @@ memPoolFree(comm_write_pool, state); fd_table[fd].rwstate = NULL; } + /* XXX isn't it strange? Previous check doesn't set state to NULL -nikita */ assert(state == NULL); fd_table[fd].rwstate = state = memPoolAlloc(comm_write_pool); state->buf = buf; @@ -878,6 +944,7 @@ state->free_func = free_func; cbdataLock(handler_data); commSetSelect(fd, COMM_SELECT_WRITE, commHandleWrite, state, 0); + checkAsyncFlag( fd ); } /* a wrapper around comm_write to allow for MemBuf to be comm_written in a snap */ --- /dev/null Wed Feb 14 00:45:56 2007 +++ squid/src/comm_cio.c Wed Feb 14 00:47:21 2007 @@ -0,0 +1,537 @@ +/* + * $Id: comm_cio.c,v 1.1.2.1 2000/12/17 14:09:08 hno Exp $ + * + * DEBUG: section 90 Signal-driven network IO + * AUTHOR: Nikita Danilov + * COPYRIGHT: This file is Copyright 2000 by Hans Reiser + * + * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from the + * Internet community. Development is led by Duane Wessels of the + * National Laboratory for Applied Network Research and funded by the + * National Science Foundation. Squid is Copyrighted (C) 1998 by + * the Regents of the University of California. Please see the + * COPYRIGHT file for full details. Squid incorporates software + * developed and/or copyrighted by other sources. Please 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. + * + */ + +/** + * Large scale description: + * + * comm_cio.c is the main file of the signal-driven network IO sub-system + * of the squid(NG), codenamed Cio Cio San (as it starts as extension + * to the Buttefly sub-system (see src/fs/butterfly/)). Traditionally + * Squid uses various polling techniques (like poll(2) and select(2)) + * to be aware of when to do IO. These interfaces have several + * drawbacks. They don't scale because the amount of work to be + * performed (by Squid and by kernel) is proportional to the total + * number of file descriptors involved rather then to the number of + * fds ready for IO. + * + * Our approach here (described at Linux fcntl(2) man page) is to + * put fd into non-blocking mode (setting O_ASYNC flag either at open + * or through fcntl) and wait for the signals that kernel start to + * deliver to the process when non-blocking IO is possible for this + * descriptor. + * + * There are several things to be noted here: + * * Linux seems to honour + * O_ASYNC only for the sockets and hence poll/select is still required + * for disk activity. + * * One have to install signal handler with SA_SIGINFO flag to get + * additional information like fd number and type of event. + * * Linux-specific fcntl( F_SETSIG ) have to be used to switch to real-time + * signals that are queued by kernel. + * [ Continuing after ugly power-failures. ] + * * It is better to explicitly wait for the signals through sigtimedwait + * than do processing in signal handler due to the obvious reason that + * very little can be done in signal handler safely. + * + * When kernel delivers IO signal to the process: + * * When incoming data arrive to the connected or accepted socket. + * * When incoming connection comes to the listening socket. + * * When some free space becomes available in outgoing TCP buffers. + * (This implies that IO signal will be not send just after call to + * socket/bind/connect.) + * + * Problems: + * * When we get an IO signal we don't know how much data we can read/write + * without blocking. Moreover the only reasonable thing we can do is to + * call appropriate Squid callback for this fd and we cannot say for sure + * that this handler will do IO at all, because callbacks are written for + * poll/select style and presuppose that if they will not do IO, they will + * be called next time, but signal will be not resent. + * * Calling sigtimedwait or friends for each signal can be big overhead + * under high load. So I implemented a version of sigtimedwait returning + * information about many signals per call. For simplicity it was implemented + * (horrors) as ioctl() supported by reiserfs-raw. + * + * To solve first problem we record information that allows us to + * understand whether we performed enough I/O to empty or fill the + * buffers. If we did not fully empty or fully fill the buffer, then + * we should not wait for a signal before doing more I/O. For this we + * set fde.flags.can_(read|write) on signal arrival. Handlers are + * called from cioCatchLostIO() for fds on which these flags are + * set. Flags are cleared only when actual IO (read/write/accept) + * returns EAGAIN, indicating that no more non-blocking IO is + * possible. Of course this costs us an additional syscall. This + * could be optimized away by modifying the kernel to record the + * amount of I/O that can be performed without blocking in the + * siginfo_t struct. + * + * How this works: + * Everyone can register interest in particular signal number by calling + * commCioAddCB( signum, callback ). SIGNUM will be blocked by this call. + * Callback will be called later when signal arrives with appopriate + * siginfo_t structure as argument. + * + * commCioLoop() grabs signals pending (without sleeping) and calls apropriate + * callbacks. Return convention mimicing that of comm_poll(). It also sets + * can_* flags. + * + * After commCioLoop() cioCatchLostIO() is called scanning fd_table for fds + * with can_* flags set and calls apropriate handlers. + * + * And of course each new TCP socket fcntled to be asynchronous. + * + * Currently there are two callbacks registered by default: + * cioStdCallback for signal SIGCIOCIOSAN and + * storeBfDirCioCallback for SIGBUTTERFLY (cf. fs/butterfly/store_dir_bf.c) + * + * */ +#include "squid.h" + +/** debugging facilities */ +#define DEBUG( format, args... ) debug( 90, 9 ) ( format "\n" , ##args ) + +/* CURRENT_FUNCTION_NAME is defined in squid.h */ + +#define TRACE0( format, args... ) \ + DEBUG( CURRENT_FUNCTION_NAME " (%s:%i): " format, \ + __FILE__, __LINE__ , ##args ) + +#define TRACE TRACE0( "" ) + +#if defined( TCP_ASYNC ) + +#include "fs/butterfly/store_bf.h" + +#include + +/** if we use ioctl in stead of sigtimedwait, ioctl_fd is descriptor + of reiserfs directory on which ioctl is issued. */ +static int ioctl_fd = -1; +/* SIGRTMAX is not constant?! */ +/** global array of per-signal-number callbacks */ +static CioCallback callbacks[ _NSIG ]; +/** bitmask of signal numbers we listen to */ +static sigset_t listenOn; +/** XXX not done. Flag indicating scanning fd_table in cioCatchLostIO() is + reasonable (should be set when commCioLoop() sets can_* flags) */ +/* static int thereIsLostIO; */ + +/** standard callback, bound to the SIGCIOCIOSAN signal number and + doing normal IO signal processing: calling of appropriate + handlers, taking deferred reads into account */ +extern int cioStdCallback( siginfo_t *info ); + +/** call this to register your own callback. SIG_NUM will be blocked + by this call. */ +int commCioAddCB( int sig_num, CioCallback callback ) +{ + TRACE; + if( callbacks[ sig_num ] == NULL ) + { + callbacks[ sig_num ] = callback; + sigaddset( &listenOn, sig_num ); + sigprocmask( SIG_BLOCK, &listenOn, NULL ); + + return 1; + } + else + { + return 0; + } +} + +/** initialize Cio Cio San */ +int initCommCio() +{ + int i; + + /* scan all configured cache dirs to find butterfly. We need + butterfly as it always works on top of a reiserfs directory and + we need one reiserfs directory to use our magic ioctl. */ + for( i = 0 ; i < Config.cacheSwap.n_configured ; i++ ) + { + SwapDir *sd; + + sd = &Config.cacheSwap.swapDirs[ i ]; + if( !strcmp( sd -> type, "butterfly" ) ) + { + ioctl_fd = ( ( bfinfo_t * ) sd -> fsdata ) -> dir; + break; + } + } + + /* as a last resort try to open this as mounted reiserfs file-system. */ + if( ioctl_fd == -1 ) + { + ioctl_fd = open( "/cache", O_RDONLY ); + } + + if( ioctl_fd > 0 ) + { + /* prepare global data structures */ + memset( callbacks, 0, sizeof callbacks ); + sigemptyset( &listenOn ); + + statCounter.syscalls.async.signals = 0; + statCounter.syscalls.async.read_sigs = 0; + statCounter.syscalls.async.write_sigs = 0; + statCounter.syscalls.async.loops = 0; + statCounter.syscalls.async.avg_ready_read = 0.0; + statCounter.syscalls.async.avg_ready_write = 0.0; + statCounter.syscalls.async.tail_reads = 0; + statCounter.syscalls.async.tail_writes = 0; + statCounter.syscalls.async.drain_reads = 0; + statCounter.syscalls.async.drain_writes = 0; + + TRACE; + commCioAddCB( SIGCIOCIOSAN, cioStdCallback ); + return 1; + } + else + { + /* will use normal sigtimedwait */ + DEBUG( "initCommCio: Keine butterfly cache_dir gefunden." + " Cio Cio San will use sigtimedwait(2).\n" ); + return 0; + } +} + +/* main signal polling loop. Uses either ioctl( REISERFS_IOC_TIMEDWAIT ) + or sigtimedwait. Calls callbacks registered for signal numbers of + signals received. Sets can_* flags in fds. */ +int commCioLoop() +{ + struct reiserfs_sigtimedwait_arg arg; + siginfo_t siginfo[ SIGINFO_PER_CALL ]; + struct timespec timeout = {0,0}; + int numOfSigs; + int ranOnce; + + arg.uthese = &listenOn; + arg.sigsetsize = 8; /* sizeof mask; */ + arg.uinfo = siginfo; + arg.uinfos = SIGINFO_PER_CALL; + arg.uts = &timeout; + + ranOnce = 0; + /* if we are using ioctl then it returns the number of signals pending + or we use normal sigtimedwait and number of signals is always 1 */ + while( ( ( ioctl_fd >= 0 ) && + ( numOfSigs = + ioctl( ioctl_fd, REISERFS_IOC_TIMEDWAIT, &arg ) ) > 0 ) || + ( ( ioctl_fd < 0 ) && + ( ( numOfSigs = 1, + sigtimedwait( &listenOn, siginfo, &timeout ) ) > 0 ) ) ) + { + int i; + + TRACE; + + ranOnce = 1; + for( i = 0 ; i < numOfSigs ; ++i ) + { + siginfo_t *info; + + info = &siginfo[ i ]; + if( callbacks[ info -> si_signo ] != NULL ) + { + if( fd_table[ info -> si_fd ].flags.async_tcp ) + { + TRACE0( "callback: fd: %i, signo: %i", + info -> si_fd, info -> si_signo ); + callbacks[ info -> si_signo ]( info ); + ++statCounter.syscalls.async.signals; + } + else if( !fd_table[ info -> si_fd ].flags.open ) + { + DEBUG + ( "commCioLoop: got signal: %i for already closed fd: %i\n", + info -> si_signo, info -> si_fd ); + } + else + { + DEBUG + ( "commCioLoop: got unexpected signal: %i for fd: %i\n", + info -> si_signo, info -> si_fd ); + } + } + else + { + DEBUG + ( "commCioLoop: got unexpected signal: %i\n", + info -> si_signo ); + } + } + } + if( ranOnce ) + { + /* we have found and processed and least one IO event */ + return COMM_OK; + } + else + { + if( ignoreErrno( errno ) ) + { + /* there was no signals pending */ + return COMM_TIMEOUT; + } + else + { + DEBUG + ( "commCioLoop: ioctl(REISERFS_IOC_TIMEDWAIT): %s\n", xstrerror() ); + /* error */ + return COMM_ERROR; + } + } +} + +/* taken from comm_select.c */ +static int commCioDeferRead( int fd ) +{ + fde *F = &fd_table[fd]; + + if( F->defer_check == NULL ) + { + return 0; + } + return F->defer_check( fd, F->defer_data ); +} + +/* we need special processing for: + o sockets listening for the HTTP connections, + o icp sockets + o dns sockets + ,,special processing`` means we have to call callbacks with special + parameters (ask someone else why) */ + +static int fdIsHttp( int fd ) +{ + int j; + + for( j = 0 ; j < NHttpSockets ; j++ ) + { + if( fd == HttpSockets[ j ] ) + { + return 1; + } + } + return 0; +} + +static int fdIsIcp( int fd ) +{ + if( fd == theInIcpConnection ) + { + return 1; + } + if( fd == theOutIcpConnection ) + { + return 1; + } + return 0; +} + +static int fdIsDns( int fd ) +{ + if( fd == DnsSocket ) + { + return 1; + } + return 0; +} + +int isDatalessSocket( int fd ) +{ + return( fdIsHttp( fd ) || fdIsIcp( fd ) || fdIsDns( fd ) ); +} + +/* see description in declaration */ +int cioStdCallback( siginfo_t *info ) +{ + int fd; + fde *f; + int result; + + fd = info -> si_fd; + f = &fd_table[ fd ]; + + assert( fd >= 0 ); + assert( f -> flags.open ); + + result = 0; + if( info -> si_band & ( POLLRDNORM | POLLIN | POLLHUP | POLLERR ) ) + { + /* non-blocking read is possible */ + fd_table[ fd ].flags.can_read = 1; + ++statCounter.syscalls.async.read_sigs; + } + if( info -> si_band & ( POLLWRNORM | POLLOUT | POLLHUP | POLLERR ) ) + { + /* non-blocking write is possible */ + fd_table[ fd ].flags.can_write = 1; + ++statCounter.syscalls.async.write_sigs; + } + /* Just sanity check. */ + if( ( !( info -> si_band & + ( POLLRDNORM | POLLIN | POLLHUP | POLLERR ) ) ) && + ( !( info -> si_band & + ( POLLWRNORM | POLLOUT | POLLHUP | POLLERR ) ) ) ) + { + DEBUG( "cioStdCallback: fd: %i strange band: %x\n", + fd, info -> si_band ); + } + return result; +} + +/* was only required for debugging. This was used + to check that fd still has O_ASYNC on, as I suspected (wrongly) + that it was cleared. Now it just returns 1 (see below) */ +/* +int checkAsyncFlag( int fd ) +{ + if( fd_table[ fd ].flags.async_tcp && + !( fcntl( fd, F_GETFL ) & O_ASYNC ) ) + { + DEBUG + ( "checkAsyncFlag: async_tcp set, but fcntl() says no! fd: %i\n", + fd ); + return 0; + } + DEBUG( "checkAsyncFlag: fd: %i ok\n", fd ); + return 1; +} +*/ + +/* process lost IOs. This emulates poll/select semantics + by calling handlers until actual IO call returns EAGAIN */ +int cioCatchLostIO() +{ + int i; + unsigned long readReady; + unsigned long writeReady; + + readReady = 0; + writeReady = 0; + + /* scan all fde table */ + for( i = 0 ; i <= Biggest_FD ; i++ ) + { + fde *F; + int dummy; + PF *handler; + int incoming; + + F = &fd_table[ i ]; + + /* + skip internal descriptors */ + /* + if( ( i > 10 ) && F -> flags.open ) + { + print_fde( F ); + } + */ + if( F -> flags.async_tcp ) + { + /* is this is socket listening for incoming HTTP connections or + DNS socket etc.? */ + incoming = -1; + if( F -> flags.can_read && ( handler = F -> read_handler ) ) + { + ++readReady; + incoming = isDatalessSocket( i ); + DEBUG( "cioCatchLostIO: FD %d lost read", i ); + if( !commCioDeferRead( i ) ) + { + F -> read_handler = NULL; + handler( i, incoming ? &dummy : F -> read_data ); + } + } + if( F -> flags.can_write && ( handler = F -> write_handler ) ) + { + ++writeReady; + if( incoming == -1 ) + { + incoming = isDatalessSocket( i ); + } + DEBUG( "cioCatchLostIO: FD %d lost write", i ); + F -> write_handler = NULL; + handler( i, incoming ? &dummy : F -> write_data ); + } + } + } + /* inductive computation of averages */ + statCounter.syscalls.async.avg_ready_write = + ( statCounter.syscalls.async.loops * + statCounter.syscalls.async.avg_ready_write + ( writeReady * 10000 ) ) / + ( statCounter.syscalls.async.loops + 1 ); + statCounter.syscalls.async.avg_ready_read = + ( statCounter.syscalls.async.loops * + statCounter.syscalls.async.avg_ready_read + ( readReady * 10000 ) ) / + ( statCounter.syscalls.async.loops + 1 ); + ++statCounter.syscalls.async.loops; + return 1; +} + +/* TCP_ASYNC */ +#endif + +int checkAsyncFlag( int fd ) +{ + return 1; +} + +/* + * $Log: comm_cio.c,v $ + * Revision 1.1.2.1 2000/12/17 14:09:08 hno + * Imported tcp_async from squidng + * + * Revision 1.1.2.5 2000/10/06 20:30:08 nikitadanilov + * Excessive dubugging removed. Preventive blocking detection as per Henrik Nordstrom proposal + * + * Revision 1.1.2.4 2000/10/05 19:31:26 nikitadanilov + * Code commented. Copyright note added. Handler stuff moved to cioCatchLostIO(). Fallback to sigtimedwait if no buttrflies are configured. + * + * Revision 1.1.2.3 2000/09/30 14:32:24 philogelos + * Ciociosan works, it seems + * + * Revision 1.1.2.2 2000/09/21 18:16:03 philogelos + * separate debug-section for ciociosan, minor changes. + * + * Revision 1.1.2.1 2000/09/12 19:47:22 philogelos + * Signal-driven async network IO. Codenamed ciociosan as requires Butterfly. + * + * + */ Index: squid/src/comm_select.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/comm_select.c,v retrieving revision 1.3 retrieving revision 1.3.22.1 diff -u -r1.3 -r1.3.22.1 --- squid/src/comm_select.c 23 Oct 2000 15:04:20 -0000 1.3 +++ squid/src/comm_select.c 17 Dec 2000 14:09:08 -0000 1.3.22.1 @@ -1,6 +1,6 @@ /* - * $Id: comm_select.c,v 1.3 2000/10/23 15:04:20 hno Exp $ + * $Id: comm_select.c,v 1.3.22.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 5 Socket Functions * @@ -206,6 +206,12 @@ for (i = npfds = 0; i < nfds; i++) { int events; fd = fds[i]; +#if defined( TCP_ASYNC ) + if( fd_table[ fd ].flags.async_tcp ) + { + continue; + } +#endif events = 0; if (fd_table[fd].read_handler) events |= POLLRDNORM; @@ -342,6 +348,13 @@ maxfd = Biggest_FD + 1; for (i = 0; i < maxfd; i++) { int events; + +#if defined( TCP_ASYNC ) + if( fd_table[ i ].flags.async_tcp ) + { + continue; + } +#endif events = 0; /* Check each open socket for a handler. */ if (fd_table[i].read_handler) { @@ -370,13 +383,15 @@ nfds++; } } +#if !defined( TCP_ASYNC ) if (nfds == 0) { assert(shutting_down); return COMM_SHUTDOWN; } +#endif if (msec > MAX_POLL_TIME) msec = MAX_POLL_TIME; - for (;;) { + for (; nfds > 0 ;) { statCounter.syscalls.polls++; num = poll(pfds, nfds, msec); statCounter.select_loops++; @@ -397,7 +412,11 @@ checkTimeouts(); } if (num == 0) +#if defined( TCP_ASYNC ) + return COMM_OK; +#else continue; +#endif /* scan each socket but the accept socket. Poll this * more frequently to minimize losses due to the 5 connect * limit in SunOS */ @@ -527,6 +546,12 @@ FD_ZERO(&read_mask); FD_ZERO(&write_mask); for (i = 0; i < nfds; i++) { +#if defined( TCP_ASYNC ) + if( fd_table[ fd ].flags.async_tcp ) + { + continue; + } +#endif fd = fds[i]; if (fd_table[fd].read_handler) { FD_SET(fd, &read_mask); Index: squid/src/debug.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/debug.c,v retrieving revision 1.3 retrieving revision 1.3.22.1 diff -u -r1.3 -r1.3.22.1 --- squid/src/debug.c 23 Oct 2000 15:04:20 -0000 1.3 +++ squid/src/debug.c 17 Dec 2000 14:09:08 -0000 1.3.22.1 @@ -1,6 +1,6 @@ /* - * $Id: debug.c,v 1.3 2000/10/23 15:04:20 hno Exp $ + * $Id: debug.c,v 1.3.22.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 0 Debug Routines * AUTHOR: Harvest Derived @@ -403,3 +403,41 @@ return ""; return Ctx_Descrs[ctx] ? Ctx_Descrs[ctx] : ""; } + +#if defined( PROFILE_SQUID ) + +#include +#include +#include +#include + +/* Beginning and end of our code segment. */ +extern void _start( void ); +extern void etext( void ); + +void tick_profiling() +{ + static time_t last_tick_time = 0; + + if( squid_curtime - last_tick_time >= PROFIL_DELAY ) + { + const char *const gmon_out = "gmon.out"; + char file_name[ 20 ]; + + last_tick_time = squid_curtime; + _mcleanup(); + snprintf( file_name, sizeof file_name, "%s.%li", + gmon_out, ( long ) last_tick_time ); + if( rename( gmon_out, file_name ) ) + { + debug( 0, 3 )( "rename: %s -> %s fails: %s\n", gmon_out, file_name, + xstrerror() ); + } + debug( 0, 3 )( "dumped profiling into %s\n", file_name ); + monstartup( ( u_long ) &_start, ( u_long ) &etext ); + } +} + +/* PROFILE_SQUID */ +#endif + Index: squid/src/disk.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/disk.c,v retrieving revision 1.4 retrieving revision 1.4.20.1 diff -u -r1.4 -r1.4.20.1 --- squid/src/disk.c 3 Nov 2000 08:39:20 -0000 1.4 +++ squid/src/disk.c 17 Dec 2000 14:09:08 -0000 1.4.20.1 @@ -1,6 +1,6 @@ /* - * $Id: disk.c,v 1.4 2000/11/03 08:39:20 hno Exp $ + * $Id: disk.c,v 1.4.20.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 6 Disk I/O Routines * AUTHOR: Harvest Derived @@ -233,8 +233,17 @@ } } while ((q = fdd->write_q)); } + else + { + CLEAR_CAN_WRITE( fd ); + } len = 0; } + else + { + CLEAR_CAN_WRITE_IF_FULL( fdd->write_q->len - fdd->write_q->buf_offset, + len, fd ); + } if (q != NULL) { /* q might become NULL from write failure above */ q->buf_offset += len; Index: squid/src/fd.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/fd.c,v retrieving revision 1.4 retrieving revision 1.4.10.1 diff -u -r1.4 -r1.4.10.1 --- squid/src/fd.c 12 Dec 2000 23:21:18 -0000 1.4 +++ squid/src/fd.c 17 Dec 2000 14:09:08 -0000 1.4.10.1 @@ -1,6 +1,6 @@ /* - * $Id: fd.c,v 1.4 2000/12/12 23:21:18 adri Exp $ + * $Id: fd.c,v 1.4.10.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 51 Filedescriptor Functions * AUTHOR: Duane Wessels @@ -189,3 +189,49 @@ RESERVED_FD, new); RESERVED_FD = new; } + +/* helper function to print file-descriptor */ +void print_fde( fde *fd ) +{ +#if defined( TCP_ASYNC ) +#define TCP_ASYNC_FORMAT "\n\tasync_tcp: %i\tcan_read: %i\tcan_write: %i" +#define TCP_ASYNC_ARGS fd -> flags.async_tcp, fd -> flags.can_read, fd -> flags.can_write, +#else +#define TCP_ASYNC_FORMAT +#define TCP_ASYNC_ARGS +#endif + if( fd != NULL ) + { + struct in_addr in; + in.s_addr = *( unsigned long int * ) &fd -> ipaddr; + debug( 51, 9 )( "fde: %i" + "\n\ttype: %i" + "\n\tlocal_port: %i\tremote_port: %i" + "\n\tipaddr: %s" + "\n\tdesc: %s" + "\n\topen: %i\tclose_request: %i\twrite_daemon: %i\tclosing: %i" + "\n\tsocket_eof: %i\tnolinger: %i\tnonblocking: %i\tipc: %i" + "\n\tcalled_connect: %i" + TCP_ASYNC_FORMAT + "\n\tbytes_read: %i\tbytes_written: %i" + "\n\tuses: %i\n", + fd - fd_table, + fd -> type, + fd -> local_port, fd -> remote_port, + inet_ntoa( in ), + fd -> desc, + fd -> flags.open, fd -> flags.close_request, + fd -> flags.write_daemon, fd -> flags.closing, + fd -> flags.socket_eof, fd -> flags.nolinger, + fd -> flags.nonblocking, fd -> flags.ipc, + fd -> flags.called_connect, + TCP_ASYNC_ARGS + fd -> bytes_read, fd -> bytes_written, + fd -> uses ); + } + else + { + debug( 51, 9 )( "\n" ); + } +} + Index: squid/src/forward.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/forward.c,v retrieving revision 1.5.4.1.2.1 retrieving revision 1.5.4.1.2.1.2.1 diff -u -r1.5.4.1.2.1 -r1.5.4.1.2.1.2.1 --- squid/src/forward.c 17 Dec 2000 13:55:39 -0000 1.5.4.1.2.1 +++ squid/src/forward.c 17 Dec 2000 14:09:08 -0000 1.5.4.1.2.1.2.1 @@ -1,6 +1,6 @@ /* - * $Id: forward.c,v 1.5.4.1.2.1 2000/12/17 13:55:39 hno Exp $ + * $Id: forward.c,v 1.5.4.1.2.1.2.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 17 Request Forwarding * AUTHOR: Duane Wessels @@ -337,7 +337,9 @@ ctimeout, fwdConnectTimeout, fwdState); + checkAsyncFlag( fd ); commConnectStart(fd, host, port, fwdConnectDone, fwdState); + checkAsyncFlag( fd ); } static void Index: squid/src/ftp.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/ftp.c,v retrieving revision 1.5.10.1 retrieving revision 1.5.10.1.4.1 diff -u -r1.5.10.1 -r1.5.10.1.4.1 --- squid/src/ftp.c 17 Dec 2000 08:20:05 -0000 1.5.10.1 +++ squid/src/ftp.c 17 Dec 2000 14:09:08 -0000 1.5.10.1.4.1 @@ -1,6 +1,6 @@ /* - * $Id: ftp.c,v 1.5.10.1 2000/12/17 08:20:05 hno Exp $ + * $Id: ftp.c,v 1.5.10.1.4.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -888,6 +888,7 @@ kb_incr(&statCounter.server.all.kbytes_in, len); kb_incr(&statCounter.server.ftp.kbytes_in, len); ftpState->data.offset += len; + CLEAR_CAN_READ_IF_EMPTY( read_sz, len, fd ); } debug(9, 5) ("ftpDataRead: FD %d, Read %d bytes\n", fd, len); if (len > 0) { @@ -902,6 +903,7 @@ if (len < 0) { debug(50, ignoreErrno(errno) ? 3 : 1) ("ftpDataRead: read error: %s\n", xstrerror()); if (ignoreErrno(errno)) { + CLEAR_CAN_READ( fd ); commSetSelect(fd, COMM_SELECT_READ, ftpDataRead, @@ -1256,11 +1258,14 @@ fd_bytes(fd, len, FD_READ); kb_incr(&statCounter.server.all.kbytes_in, len); kb_incr(&statCounter.server.ftp.kbytes_in, len); + CLEAR_CAN_READ_IF_EMPTY( ftpState->ctrl.size - ftpState->ctrl.offset, + len, fd ); } debug(9, 5) ("ftpReadControlReply: FD %d, Read %d bytes\n", fd, len); if (len < 0) { debug(50, ignoreErrno(errno) ? 3 : 1) ("ftpReadControlReply: read error: %s\n", xstrerror()); if (ignoreErrno(errno)) { + CLEAR_CAN_READ( fd ); ftpScheduleReadControlReply(ftpState, 0); } else { ftpFailed(ftpState, ERR_READ_ERROR); Index: squid/src/gopher.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/gopher.c,v retrieving revision 1.5.4.1 retrieving revision 1.5.4.1.4.1 diff -u -r1.5.4.1 -r1.5.4.1.4.1 --- squid/src/gopher.c 17 Dec 2000 08:20:05 -0000 1.5.4.1 +++ squid/src/gopher.c 17 Dec 2000 14:09:08 -0000 1.5.4.1.4.1 @@ -1,6 +1,6 @@ /* - * $Id: gopher.c,v 1.5.4.1 2000/12/17 08:20:05 hno Exp $ + * $Id: gopher.c,v 1.5.4.1.4.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 10 Gopher * AUTHOR: Harvest Derived @@ -620,18 +620,18 @@ #endif kb_incr(&statCounter.server.all.kbytes_in, len); kb_incr(&statCounter.server.other.kbytes_in, len); - } - debug(10, 5) ("gopherReadReply: FD %d read len=%d\n", fd, len); - if (len > 0) { + CLEAR_CAN_READ_IF_EMPTY( read_sz, len, fd ); commSetTimeout(fd, Config.Timeout.read, NULL, NULL); IOStats.Gopher.reads++; for (clen = len - 1, bin = 0; clen; bin++) clen >>= 1; IOStats.Gopher.read_hist[bin]++; } + debug(10, 5) ("gopherReadReply: FD %d read len=%d\n", fd, len); if (len < 0) { debug(50, 1) ("gopherReadReply: error reading: %s\n", xstrerror()); if (ignoreErrno(errno)) { + CLEAR_CAN_READ( fd ); commSetSelect(fd, COMM_SELECT_READ, gopherReadReply, data, 0); } else if (entry->mem_obj->inmem_hi == 0) { ErrorState *err; Index: squid/src/http.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/http.c,v retrieving revision 1.5.10.1 retrieving revision 1.5.10.1.4.1 diff -u -r1.5.10.1 -r1.5.10.1.4.1 --- squid/src/http.c 17 Dec 2000 08:20:05 -0000 1.5.10.1 +++ squid/src/http.c 17 Dec 2000 14:09:08 -0000 1.5.10.1.4.1 @@ -1,6 +1,6 @@ /* - * $Id: http.c,v 1.5.10.1 2000/12/17 08:20:05 hno Exp $ + * $Id: http.c,v 1.5.10.1.4.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -497,6 +497,7 @@ for (clen = len - 1, bin = 0; clen; bin++) clen >>= 1; IOStats.Http.read_hist[bin]++; + CLEAR_CAN_READ_IF_EMPTY( read_sz, len, fd ); } if (!httpState->reply_hdr && len > 0) { /* Skip whitespace */ @@ -512,6 +513,7 @@ debug(50, 2) ("httpReadReply: FD %d: read failure: %s.\n", fd, xstrerror()); if (ignoreErrno(errno)) { + CLEAR_CAN_READ( fd ); commSetSelect(fd, COMM_SELECT_READ, httpReadReply, httpState, 0); } else if (entry->mem_obj->inmem_hi == 0) { ErrorState *err; Index: squid/src/main.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/main.c,v retrieving revision 1.6.4.1 retrieving revision 1.6.4.1.4.1 diff -u -r1.6.4.1 -r1.6.4.1.4.1 --- squid/src/main.c 17 Dec 2000 08:20:05 -0000 1.6.4.1 +++ squid/src/main.c 17 Dec 2000 14:09:08 -0000 1.6.4.1.4.1 @@ -1,6 +1,6 @@ /* - * $Id: main.c,v 1.6.4.1 2000/12/17 08:20:05 hno Exp $ + * $Id: main.c,v 1.6.4.1.4.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -562,6 +562,11 @@ eventAdd("ipcache_purgelru", ipcache_purgelru, NULL, 10.0, 1); eventAdd("fqdncache_purgelru", fqdncache_purgelru, NULL, 15.0, 1); } + +#if defined( TCP_ASYNC ) + initCommCio(); +#endif + configured_once = 1; } @@ -716,6 +721,35 @@ eventRun(); if ((loop_delay = eventNextTime()) < 0) loop_delay = 0; +#if defined( TCP_ASYNC ) + /* cannot remove poll/select loops at this time, bacause disk IO + doesn't use signals yet */ + switch( commCioLoop() ) { + case COMM_OK: + errcount = 0; /* reset if successful */ + break; + case COMM_ERROR: + errcount++; + debug( 90, 1 ) ("Ciociosan select loop Error. Retry %d\n", errcount); + if (errcount == 10) + fatal_dump("Select Loop failed!"); + break; + case COMM_TIMEOUT: + break; + case COMM_SHUTDOWN: + SquidShutdown(NULL); + break; + default: + fatal_dump("MAIN: Internal error -- this should never happen."); + break; + } + cioCatchLostIO(); +/* TCP_ASYNC */ +#endif +#if defined( PROFILE_SQUID ) + tick_profiling(); +/* PROFILE_SQUID */ +#endif #if HAVE_POLL switch (comm_poll(loop_delay)) { #else Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.6.4.1.2.1 retrieving revision 1.6.4.1.2.1.2.1 diff -u -r1.6.4.1.2.1 -r1.6.4.1.2.1.2.1 --- squid/src/protos.h 17 Dec 2000 13:55:39 -0000 1.6.4.1.2.1 +++ squid/src/protos.h 17 Dec 2000 14:09:08 -0000 1.6.4.1.2.1.2.1 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.6.4.1.2.1 2000/12/17 13:55:39 hno Exp $ + * $Id: protos.h,v 1.6.4.1.2.1.2.1 2000/12/17 14:09:08 hno Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -198,6 +198,10 @@ /* packs, then prints an object using debug() */ extern void debugObj(int section, int level, const char *label, void *obj, ObjPackMethod pm); +#if defined( PROFILE_SQUID ) +extern void tick_profiling(); +#endif + /* disk.c */ extern int file_open(const char *path, int mode); extern void file_close(int fd); @@ -238,6 +242,7 @@ extern void eventFreeMemory(void); extern int eventFind(EVH *, void *); +/* fd.c */ extern void fd_close(int fd); extern void fd_open(int fd, unsigned int type, const char *); extern void fd_note(int fd, const char *); @@ -246,6 +251,7 @@ extern void fdDumpOpen(void); extern int fdNFree(void); extern void fdAdjustReserved(void); +extern void print_fde( fde *fd ); extern fileMap *file_map_create(void); extern int file_map_allocate(fileMap *, int); @@ -1215,6 +1221,17 @@ #endif /* + * comm_cio.h + */ + +#if defined( TCP_ASYNC ) +extern int commCioAddCB( int sig_num, CioCallback callback ); +extern int commCioLoop(); +extern int cioCatchLostIO(); +extern int initCommCio(); +#endif +extern int checkAsyncFlag( int fd ); +/* * Removal Policies */ extern RemovalPolicy *createRemovalPolicy(RemovalPolicySettings * settings); Index: squid/src/pump.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/Attic/pump.c,v retrieving revision 1.4.14.1 retrieving revision 1.4.14.1.4.1 diff -u -r1.4.14.1 -r1.4.14.1.4.1 --- squid/src/pump.c 17 Dec 2000 08:20:05 -0000 1.4.14.1 +++ squid/src/pump.c 17 Dec 2000 14:09:08 -0000 1.4.14.1.4.1 @@ -1,6 +1,6 @@ /* - * $Id: pump.c,v 1.4.14.1 2000/12/17 08:20:05 hno Exp $ + * $Id: pump.c,v 1.4.14.1.4.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 61 PUMP handler * AUTHOR: Kostas Anagnostakis @@ -235,10 +235,12 @@ debug(61, 5) ("pumpReadFromClient: FD %d: len %d.\n", fd, len); if (len > 0) { (void) 0; /* continue */ + CLEAR_CAN_READ_IF_EMPTY( bytes_to_read, len, fd ); } else if (len < 0) { debug(61, 2) ("pumpReadFromClient: FD %d: read failure: %s.\n", fd, xstrerror()); if (ignoreErrno(errno)) { + CLEAR_CAN_READ( fd ); debug(61, 5) ("pumpReadFromClient: FD %d: len %d and ignore!\n", fd, len); commSetSelect(fd, Index: squid/src/squid.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/squid.h,v retrieving revision 1.3.16.1.2.1 retrieving revision 1.3.16.1.2.1.2.1 diff -u -r1.3.16.1.2.1 -r1.3.16.1.2.1.2.1 --- squid/src/squid.h 17 Dec 2000 13:55:39 -0000 1.3.16.1.2.1 +++ squid/src/squid.h 17 Dec 2000 14:09:08 -0000 1.3.16.1.2.1.2.1 @@ -1,6 +1,6 @@ /* - * $Id: squid.h,v 1.3.16.1.2.1 2000/12/17 13:55:39 hno Exp $ + * $Id: squid.h,v 1.3.16.1.2.1.2.1 2000/12/17 14:09:08 hno Exp $ * * AUTHOR: Duane Wessels * @@ -89,6 +89,85 @@ #define assert(EX) ((EX)?((void)0):xassert("EX", __FILE__, __LINE__)) #endif +#define LINGERING_CLOSE 1 + +/* + SIGIO-driven IO hack. Don't look here. + You are not supposed to understand this. -- nikita. +*/ +/* #define TCP_ASYNC */ +#if defined( TCP_ASYNC ) + +/* It's Butterfly's real name */ +#define SIGCIOCIOSAN ( SIGRTMIN + 8 ) + +#define SIGINFO_PER_CALL 128 + +/* this should be done before #include , + because we need F_SETSIG. */ +#define _GNU_SOURCE + +#if HAVE_SIGNAL_H +#include +#endif + +#if defined( __GNUC__ ) +#define CURRENT_FUNCTION_NAME __PRETTY_FUNCTION__ +#else +#define CURRENT_FUNCTION_NAME __FUNC__ +#endif + +#define CLEAR_CAN_READ_INTERNAL( fd ) \ + debug( 90, 9 )( CURRENT_FUNCTION_NAME ": cleared can_read.\n" ); \ + fd_table[ fd ].flags.can_read = 0 + +#define CLEAR_CAN_WRITE_INTERNAL( fd ) \ + debug( 90, 9 )( CURRENT_FUNCTION_NAME ": cleared can_write.\n" ); \ + fd_table[ fd ].flags.can_write = 0 + +#define CLEAR_CAN_READ( fd ) do { \ + CLEAR_CAN_READ_INTERNAL( fd ); \ + ++statCounter.syscalls.async.tail_reads; } while( 0 ) + +#define CLEAR_CAN_WRITE( fd ) do { \ + CLEAR_CAN_WRITE_INTERNAL( fd ); \ + ++statCounter.syscalls.async.tail_writes; } while( 0 ) + +#define CLEAR_CAN_READ_IF_EMPTY( requestedSize, actuallyRead, fd ) \ + do \ + { \ + if( ( actuallyRead > 0 ) && ( actuallyRead < requestedSize ) ) \ + { \ + /* CLEAR_CAN_READ_INTERNAL( fd ); */ \ + ++statCounter.syscalls.async.drain_reads; \ + } \ + } \ + while( 0 ) + +#define CLEAR_CAN_WRITE_IF_FULL( requestedSize, actuallyWritten, fd ) \ + do \ + { \ + if( ( actuallyWritten > 0 ) && ( actuallyWritten < requestedSize ) ) \ + { \ + /* CLEAR_CAN_WRITE_INTERNAL( fd ); */ \ + ++statCounter.syscalls.async.drain_writes; \ + } \ + } \ + while( 0 ) + +#else + +#define CLEAR_CAN_READ( fd ) do {} while( 0 ) +#define CLEAR_CAN_WRITE( fd ) do {} while( 0 ) +#define CLEAR_CAN_READ_IF_EMPTY( requestedSize, actuallyRead, fd ) \ + do {} while( 0 ) +#define CLEAR_CAN_WRITE_IF_FULL( requestedSize, actuallyWritten, fd ) \ + do {} while( 0 ) + +/* TCP_ASYNC */ +#endif + + #if HAVE_UNISTD_H #include #endif Index: squid/src/ssl.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/ssl.c,v retrieving revision 1.3.16.1 retrieving revision 1.3.16.1.4.1 diff -u -r1.3.16.1 -r1.3.16.1.4.1 --- squid/src/ssl.c 17 Dec 2000 08:20:05 -0000 1.3.16.1 +++ squid/src/ssl.c 17 Dec 2000 14:09:08 -0000 1.3.16.1.4.1 @@ -1,6 +1,6 @@ /* - * $Id: ssl.c,v 1.3.16.1 2000/12/17 08:20:05 hno Exp $ + * $Id: ssl.c,v 1.3.16.1.4.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -210,6 +210,7 @@ kb_incr(&statCounter.server.all.kbytes_in, len); kb_incr(&statCounter.server.other.kbytes_in, len); sslState->server.len += len; + CLEAR_CAN_READ_IF_EMPTY( read_sz, len, fd ); } cbdataLock(sslState); if (len < 0) { @@ -217,8 +218,11 @@ ("sslReadServer: FD %d: read failure: %s\n", fd, xstrerror()); if (!ignoreErrno(errno)) comm_close(fd); - } else if (len == 0) { + } else { + CLEAR_CAN_READ( fd ); + if (len == 0) { comm_close(sslState->server.fd); + } } if (cbdataValid(sslState)) sslSetSelect(sslState); @@ -244,6 +248,8 @@ fd_bytes(fd, len, FD_READ); kb_incr(&statCounter.client_http.kbytes_in, len); sslState->client.len += len; + CLEAR_CAN_READ_IF_EMPTY( SQUID_TCP_SO_RCVBUF - sslState->client.len, + len, fd ); } cbdataLock(sslState); if (len < 0) { @@ -253,7 +259,10 @@ level = 2; #endif if (ignoreErrno(errno)) + { + CLEAR_CAN_READ( fd ); level = 3; + } debug(50, level) ("sslReadClient: FD %d: read failure: %s\n", fd, xstrerror()); if (!ignoreErrno(errno)) @@ -285,6 +294,7 @@ kb_incr(&statCounter.server.all.kbytes_out, len); kb_incr(&statCounter.server.other.kbytes_out, len); assert(len <= sslState->client.len); + CLEAR_CAN_WRITE_IF_FULL( sslState->client.len, len, fd ); sslState->client.len -= len; if (sslState->client.len > 0) { /* we didn't write the whole thing */ @@ -299,6 +309,10 @@ ("sslWriteServer: FD %d: write failure: %s.\n", fd, xstrerror()); if (!ignoreErrno(errno)) comm_close(fd); + else + { + CLEAR_CAN_WRITE( fd ); + } } if (cbdataValid(sslState)) sslSetSelect(sslState); @@ -323,6 +337,7 @@ fd_bytes(fd, len, FD_WRITE); kb_incr(&statCounter.client_http.kbytes_out, len); assert(len <= sslState->server.len); + CLEAR_CAN_WRITE_IF_FULL( sslState->server.len, len, fd ); sslState->server.len -= len; /* increment total object size */ if (sslState->size_ptr) @@ -340,6 +355,10 @@ ("sslWriteClient: FD %d: write failure: %s.\n", fd, xstrerror()); if (!ignoreErrno(errno)) comm_close(fd); + else + { + CLEAR_CAN_WRITE( fd ); + } } if (cbdataValid(sslState)) sslSetSelect(sslState); Index: squid/src/stat.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/stat.c,v retrieving revision 1.4.14.1.2.1 retrieving revision 1.4.14.1.2.1.2.1 diff -u -r1.4.14.1.2.1 -r1.4.14.1.2.1.2.1 --- squid/src/stat.c 17 Dec 2000 13:55:39 -0000 1.4.14.1.2.1 +++ squid/src/stat.c 17 Dec 2000 14:09:08 -0000 1.4.14.1.2.1.2.1 @@ -1,6 +1,6 @@ /* - * $Id: stat.c,v 1.4.14.1.2.1 2000/12/17 13:55:39 hno Exp $ + * $Id: stat.c,v 1.4.14.1.2.1.2.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 18 Cache Manager Statistics * AUTHOR: Harvest Derived @@ -803,33 +803,52 @@ storeAppendPrintf(sentry, "aborted_requests = %f/sec\n", XAVG(aborted_requests)); +#define ADD_SXAVG_ENTRY( x ) \ + storeAppendPrintf \ + ( sentry, "syscalls." #x " = %f/sec\n", XAVG( syscalls.x ) ) + #if HAVE_POLL - storeAppendPrintf(sentry, "syscalls.polls = %f/sec\n", XAVG(syscalls.polls)); + ADD_SXAVG_ENTRY( polls ); #else - storeAppendPrintf(sentry, "syscalls.selects = %f/sec\n", XAVG(syscalls.selects)); + ADD_SXAVG_ENTRY( selects ); +#endif + ADD_SXAVG_ENTRY( disk.opens ); + ADD_SXAVG_ENTRY( disk.closes ); + ADD_SXAVG_ENTRY( disk.reads ); + ADD_SXAVG_ENTRY( disk.writes ); + ADD_SXAVG_ENTRY( disk.seeks ); + ADD_SXAVG_ENTRY( disk.unlinks ); + ADD_SXAVG_ENTRY( disk.truncates ); + ADD_SXAVG_ENTRY( disk.utimes ); + ADD_SXAVG_ENTRY( disk.stats ); + + ADD_SXAVG_ENTRY( sock.accepts ); + ADD_SXAVG_ENTRY( sock.sockets ); + ADD_SXAVG_ENTRY( sock.connects ); + ADD_SXAVG_ENTRY( sock.binds ); + ADD_SXAVG_ENTRY( sock.closes ); + ADD_SXAVG_ENTRY( sock.reads ); + ADD_SXAVG_ENTRY( sock.writes ); + ADD_SXAVG_ENTRY( sock.recvfroms ); + ADD_SXAVG_ENTRY( sock.sendtos ); + +#if defined( TCP_ASYNC ) + ADD_SXAVG_ENTRY( async.signals ); + ADD_SXAVG_ENTRY( async.read_sigs ); + ADD_SXAVG_ENTRY( async.write_sigs ); + ADD_SXAVG_ENTRY( async.loops ); + ADD_SXAVG_ENTRY( async.avg_ready_read ); + ADD_SXAVG_ENTRY( async.avg_ready_write ); + ADD_SXAVG_ENTRY( async.tail_reads ); + ADD_SXAVG_ENTRY( async.tail_writes ); + ADD_SXAVG_ENTRY( async.drain_reads ); + ADD_SXAVG_ENTRY( async.drain_writes ); #endif - storeAppendPrintf(sentry, "syscalls.disk.opens = %f/sec\n", XAVG(syscalls.disk.opens)); - storeAppendPrintf(sentry, "syscalls.disk.closes = %f/sec\n", XAVG(syscalls.disk.closes)); - storeAppendPrintf(sentry, "syscalls.disk.reads = %f/sec\n", XAVG(syscalls.disk.reads)); - storeAppendPrintf(sentry, "syscalls.disk.writes = %f/sec\n", XAVG(syscalls.disk.writes)); - storeAppendPrintf(sentry, "syscalls.disk.seeks = %f/sec\n", XAVG(syscalls.disk.seeks)); - storeAppendPrintf(sentry, "syscalls.disk.unlinks = %f/sec\n", XAVG(syscalls.disk.unlinks)); - storeAppendPrintf(sentry, "syscalls.disk.truncates = %f/sec\n", XAVG(syscalls.disk.truncates)); - storeAppendPrintf(sentry, "syscalls.disk.utimes = %f/sec\n", XAVG(syscalls.disk.utimes)); - storeAppendPrintf(sentry, "syscalls.disk.stats = %f/sec\n", XAVG(syscalls.disk.stats)); - storeAppendPrintf(sentry, "syscalls.sock.accepts = %f/sec\n", XAVG(syscalls.sock.accepts)); - storeAppendPrintf(sentry, "syscalls.sock.sockets = %f/sec\n", XAVG(syscalls.sock.sockets)); - storeAppendPrintf(sentry, "syscalls.sock.connects = %f/sec\n", XAVG(syscalls.sock.connects)); - storeAppendPrintf(sentry, "syscalls.sock.binds = %f/sec\n", XAVG(syscalls.sock.binds)); - storeAppendPrintf(sentry, "syscalls.sock.closes = %f/sec\n", XAVG(syscalls.sock.closes)); - storeAppendPrintf(sentry, "syscalls.sock.reads = %f/sec\n", XAVG(syscalls.sock.reads)); - storeAppendPrintf(sentry, "syscalls.sock.writes = %f/sec\n", XAVG(syscalls.sock.writes)); - storeAppendPrintf(sentry, "syscalls.sock.recvfroms = %f/sec\n", XAVG(syscalls.sock.recvfroms)); - storeAppendPrintf(sentry, "syscalls.sock.sendtos = %f/sec\n", XAVG(syscalls.sock.sendtos)); storeAppendPrintf(sentry, "cpu_time = %f seconds\n", ct); storeAppendPrintf(sentry, "wall_time = %f seconds\n", dt); storeAppendPrintf(sentry, "cpu_usage = %f%%\n", dpercent(ct, dt)); +#undef ADD_SXAVG_ENTRY } @@ -1170,6 +1189,25 @@ (int) f->cd.kbytes_recv.kb); #endif +#if defined( TCP_ASYNC ) +#define ADD_ENTRY( x ) \ + storeAppendPrintf \ + ( sentry, "syscalls." #x " = %i\n", f -> syscalls.x ); + + ADD_ENTRY( async.signals ); + ADD_ENTRY( async.read_sigs ); + ADD_ENTRY( async.write_sigs ); + ADD_ENTRY( async.loops ); + ADD_ENTRY( async.avg_ready_read ); + ADD_ENTRY( async.avg_ready_write ); + ADD_ENTRY( async.tail_reads ); + ADD_ENTRY( async.tail_writes ); + ADD_ENTRY( async.drain_reads ); + ADD_ENTRY( async.drain_writes ); + +#undef ADD_ENTRY +#endif + storeAppendPrintf(sentry, "unlink.requests = %d\n", f->unlink.requests); storeAppendPrintf(sentry, "page_faults = %d\n", Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.8.8.1 retrieving revision 1.8.8.1.2.1 diff -u -r1.8.8.1 -r1.8.8.1.2.1 --- squid/src/structs.h 17 Dec 2000 13:55:39 -0000 1.8.8.1 +++ squid/src/structs.h 17 Dec 2000 14:09:08 -0000 1.8.8.1.2.1 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.8.8.1 2000/12/17 13:55:39 hno Exp $ + * $Id: structs.h,v 1.8.8.1.2.1 2000/12/17 14:09:08 hno Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -600,6 +600,11 @@ unsigned int nonblocking:1; unsigned int ipc:1; unsigned int called_connect:1; +#ifdef TCP_ASYNC + unsigned int async_tcp:1; + unsigned int can_read:1; + unsigned int can_write:1; +#endif } flags; int bytes_read; int bytes_written; @@ -1652,6 +1657,21 @@ int recvfroms; int sendtos; } sock; +#if defined( TCP_ASYNC ) + struct { + int signals; + int read_sigs; + int write_sigs; + int loops; + int avg_ready_read; + int avg_ready_write; + int tail_reads; + int tail_writes; + int drain_reads; + int drain_writes; + } async; +/* TCP_ASYNC */ +#endif #if HAVE_POLL int polls; #else Index: squid/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v retrieving revision 1.4.10.1.2.1 retrieving revision 1.4.10.1.2.1.2.1 diff -u -r1.4.10.1.2.1 -r1.4.10.1.2.1.2.1 --- squid/src/typedefs.h 17 Dec 2000 13:55:40 -0000 1.4.10.1.2.1 +++ squid/src/typedefs.h 17 Dec 2000 14:09:08 -0000 1.4.10.1.2.1.2.1 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.4.10.1.2.1 2000/12/17 13:55:40 hno Exp $ + * $Id: typedefs.h,v 1.4.10.1.2.1.2.1 2000/12/17 14:09:08 hno Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -316,4 +316,10 @@ typedef int STDIRSELECT(const StoreEntry *); +/* + * comm_cio.h + */ + typedef int ( *CioCallback ) ( siginfo_t *info ); + + #endif /* _TYPEDEFS_H_ */ Index: squid/src/wais.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/wais.c,v retrieving revision 1.3.16.1 retrieving revision 1.3.16.1.4.1 diff -u -r1.3.16.1 -r1.3.16.1.4.1 --- squid/src/wais.c 17 Dec 2000 08:20:05 -0000 1.3.16.1 +++ squid/src/wais.c 17 Dec 2000 14:09:08 -0000 1.3.16.1.4.1 @@ -1,6 +1,6 @@ /* - * $Id: wais.c,v 1.3.16.1 2000/12/17 08:20:05 hno Exp $ + * $Id: wais.c,v 1.3.16.1.4.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 24 WAIS Relay * AUTHOR: Harvest Derived @@ -119,11 +119,13 @@ for (clen = len - 1, bin = 0; clen; bin++) clen >>= 1; IOStats.Wais.read_hist[bin]++; + CLEAR_CAN_READ_IF_EMPTY( read_sz, len, fd ); } if (len < 0) { debug(50, 1) ("waisReadReply: FD %d: read failure: %s.\n", fd, xstrerror()); if (ignoreErrno(errno)) { + CLEAR_CAN_READ( fd ); /* reinstall handlers */ /* XXX This may loop forever */ commSetSelect(fd, COMM_SELECT_READ, Index: squid/src/whois.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/whois.c,v retrieving revision 1.3.16.1 retrieving revision 1.3.16.1.4.1 diff -u -r1.3.16.1 -r1.3.16.1.4.1 --- squid/src/whois.c 17 Dec 2000 08:20:05 -0000 1.3.16.1 +++ squid/src/whois.c 17 Dec 2000 14:09:08 -0000 1.3.16.1.4.1 @@ -1,6 +1,6 @@ /* - * $Id: whois.c,v 1.3.16.1 2000/12/17 08:20:05 hno Exp $ + * $Id: whois.c,v 1.3.16.1.4.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 75 WHOIS protocol * AUTHOR: Duane Wessels, Kostas Anagnostakis @@ -104,11 +104,13 @@ kb_incr(&statCounter.server.http.kbytes_in, len); storeAppend(entry, buf, len); commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read); + CLEAR_CAN_READ_IF_EMPTY( 4095, len, fd ); } else if (len < 0) { debug(50, 2) ("whoisReadReply: FD %d: read failure: %s.\n", fd, xstrerror()); if (ignoreErrno(errno)) { - commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read); + CLEAR_CAN_READ( fd ); + commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read); } else if (mem->inmem_hi == 0) { ErrorState *err; err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR); Index: squid/src/fs/butterfly/store_dir_bf.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/fs/butterfly/Attic/store_dir_bf.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.1.2.1 diff -u -r1.1.2.1 -r1.1.2.1.2.1 --- squid/src/fs/butterfly/store_dir_bf.c 17 Dec 2000 13:55:40 -0000 1.1.2.1 +++ squid/src/fs/butterfly/store_dir_bf.c 17 Dec 2000 14:09:08 -0000 1.1.2.1.2.1 @@ -1,6 +1,6 @@ /* - * $Id: store_dir_bf.c,v 1.1.2.1 2000/12/17 13:55:40 hno Exp $ + * $Id: store_dir_bf.c,v 1.1.2.1.2.1 2000/12/17 14:09:08 hno Exp $ * * DEBUG: section 86 Store Directory, the "Butterfly" version * AUTHOR: Yury Shevchuk @@ -190,6 +190,29 @@ safe_free(bf_dir_index); } +#if 0 && defined( TCP_ASYNC ) +static int +storeBfDirCioCallback( siginfo_t *info ) +{ + if( info -> si_signo == SIGBUTTERFLY ) + { + /* BTW, easy way to crash squid: send squid + SIGBUTTERFLY with no info, and we'll crash on bad + pointer. (Assuming you have the right to send us + signals) */ + bfop_t *op = info -> si_value.sival_ptr; + if (! op) { + debug(86, 1) + ("storeBfDirCallback: got SIGBUTTERFLY w/o siginfo!\n"); + return 0; + } + storeBfOpCompletion (op); + } + return 1; +} +/* TCP_ASYNC */ +#endif + static void storeBfDirInit(SwapDir * sd) { @@ -221,6 +244,11 @@ comm_quick_poll_required(); storeBfDirOpenSwapLog(sd); storeBfDirRebuild(sd); +#if 0 && defined( TCP_ASYNC ) + debug(50, 0) ("storeBfDirInit: commCioAddCB\n"); + commCioAddCB( SIGBUTTERFLY, storeBfDirCioCallback ); +/* TCP_ASYNC */ +#endif } @@ -972,3 +1000,29 @@ } bf_initialised = 1; } + +/* + * $Log: store_dir_bf.c,v $ + * Revision 1.1.2.1.2.1 2000/12/17 14:09:08 hno + * Imported tcp_async from squidng + * + * Revision 1.1.2.7.2.3 2000/10/12 15:06:25 nikitadanilov + * Small typo corrected + * + * Revision 1.1.2.7.2.2 2000/10/10 11:37:30 nikitadanilov + * Merged changes from reiserfs_raw + * + * Revision 1.1.2.7.2.1 2000/09/12 19:47:23 philogelos + * Signal-driven async network IO. Codenamed ciociosan as requires Butterfly. + * + * Revision 1.1.2.2.2.2 2000/08/30 16:41:59 sizif + * filter by incoming signo (only SIGBUTTERFLIEs matter) + * + * Revision 1.1.2.2.2.1 2000/08/29 18:14:17 sizif + * sigtimedwait-like ioctl added + * + * + * Local Variables: + * tab-width: 8 + * End: + */