cvs commit: apachen/src/main buff.c
dgaudet 98/01/26 21:35:34 Modified:.STATUS src CHANGES src/main buff.c Log: really fix Rasmus' chunking problem this time introduce LARGE_WRITE_THRESHOLD tunable for determining when large_write() is a good idea Reviewed by: Rasmus Lerdorf Revision ChangesPath 1.132 +1 -1 apachen/STATUS Index: STATUS === RCS file: /export/home/cvs/apachen/STATUS,v retrieving revision 1.131 retrieving revision 1.132 diff -u -r1.131 -r1.132 --- STATUS1998/01/26 19:50:05 1.131 +++ STATUS1998/01/27 05:35:22 1.132 @@ -70,7 +70,7 @@ * Dean's [PATCH] ap_snprintf should be more sane (fwd) * Jim's/Ken's move of main/util_snprintf.c to ap/ap_snprintf.c * [PATCH] Re: [BUGFIXES] Wrong GID for PID file and UMASK for logs -* Dean's [PATCH] fix Rasmus' chunking error +* Dean's [PATCH] fix Rasmus' chunking error (take 2, really fix it) * [PATCH] PR#1366: fix result of send_fd_length * Ben Hyde's [PATCH] Finish suite of mutex ops for non-threaded platforms * Ben Hyde's [PATCH] Serialize the update to pool.sub_* in destroy_pool 1.601 +15 -5 apachen/src/CHANGES Index: CHANGES === RCS file: /export/home/cvs/apachen/src/CHANGES,v retrieving revision 1.600 retrieving revision 1.601 diff -u -r1.600 -r1.601 --- CHANGES 1998/01/26 19:50:08 1.600 +++ CHANGES 1998/01/27 05:35:27 1.601 @@ -241,11 +241,21 @@ *) send_fd_length() did not calculate total_bytes_sent properly. [Ben Reser [EMAIL PROTECTED]] PR#1366 - *) The large_write() changes tickled a bug in bputc(), this would - show up as certain modules not working with Internet Explorer 4.0. - Fix this bug, and also fix a performance bug related to bputc() - causing a large_write() -- don't do large_write() unless there's - at least two bytes to write. [Dean Gaudet] + *) The bputc() macro was not properly integrated with the chunking + code; in many cases modules using bputc() could cause completely + bogus chunked output. (Typically this will show up as problems + with Internet Explorer 4.0 reading a page, but other browsers + having no problem.) [Dean Gaudet] + + *) Create LARGE_WRITE_THRESHOLD define which determines how many + bytes have to be supplied to bwrite() before it will consider + doing a writev() to assemble multiple buffers in one system + call. This is critical for modules such as mod_include, + mod_autoindex, mod_php3 which all use bputc()/bputs() of smaller + strings in some cases. The result would be extra effort + setting up writev(), and in many cases extra effort building + chunks. The default is 31, it can be override at compile + time. [Dean Gaudet] *) Move the gid switching code into the child so that log files and pid files are opened with the root gid. 1.60 +39 -12apachen/src/main/buff.c Index: buff.c === RCS file: /export/home/cvs/apachen/src/main/buff.c,v retrieving revision 1.59 retrieving revision 1.60 diff -u -r1.59 -r1.60 --- buff.c1998/01/26 16:46:07 1.59 +++ buff.c1998/01/27 05:35:32 1.60 @@ -71,7 +71,21 @@ #include bstring.h /* for IRIX, FD_SET calls bzero() */ #endif +#ifndef DEFAULT_BUFSIZE #define DEFAULT_BUFSIZE (4096) +#endif + +/* bwrite()s of greater than this size can result in a large_write() call, + * which can result in a writev(). It's a little more work to set up the + * writev() rather than copy bytes into the buffer, so we don't do it for small + * writes. This is especially important when chunking (which is a very likely + * source of small writes if it's a module using bputc/bputs)... because we + * have the expense of actually building two chunks for each writev(). + */ +#ifndef LARGE_WRITE_THRESHOLD +#define LARGE_WRITE_THRESHOLD 31 +#endif + /* * Buffered I/O routines. @@ -347,7 +361,13 @@ } /* - * start chunked encoding + * Start chunked encoding. + * + * Note that in order for bputc() to be an efficient macro we have to guarantee + * that start_chunk() has always been called on the buffer before we leave any + * routine in this file. Said another way, if a routine here uses end_chunk() + * and writes something on the wire, then it has to call start_chunk() or set + * an error condition before returning. */ static void start_chunk(BUFF *fb) { @@ -865,16 +885,9 @@ API_EXPORT(int) bflsbuf(int c, BUFF *fb) { char ss[1]; -int rc; ss[0] = c; -rc = bwrite(fb, ss, 1); -/* We do
cvs commit: apachen/src/main buff.c
dgaudet 98/01/22 13:00:07 Modified:src/main buff.c Log: document doerror() a little better Submitted by: Ben Hyde Reviewed by: Dean Gaudet Revision ChangesPath 1.58 +3 -6 apachen/src/main/buff.c Index: buff.c === RCS file: /export/home/cvs/apachen/src/main/buff.c,v retrieving revision 1.57 retrieving revision 1.58 diff -u -r1.57 -r1.58 --- buff.c1998/01/16 14:22:54 1.57 +++ buff.c1998/01/22 21:00:06 1.58 @@ -247,16 +247,13 @@ return rv; } -static void doerror(BUFF *fb, int err) +static void doerror(BUFF *fb, int direction) { int errsave = errno; /* Save errno to prevent overwriting it below */ -if (err == B_RD) - fb-flags |= B_RDERR; -else - fb-flags |= B_WRERR; +fb-flags |= (direction == B_RD ? B_RDERR : B_WRERR); if (fb-error != NULL) - (*fb-error) (fb, err, fb-error_data); + (*fb-error) (fb, direction, fb-error_data); errno = errsave; }
cvs commit: apachen/src/main buff.c
dgaudet 97/12/26 10:21:47 Modified:.STATUS src CHANGES src/main buff.c Log: Fix problem with chunking and bputc(). Don't use large_write() when nbytes == 1... otherwise we have really bad performance at end of buffer with bputc(). Reviewed by: Rasmus Lerdorf, Jim Jagielski Revision ChangesPath 1.31 +5 -4 apachen/STATUS Index: STATUS === RCS file: /export/home/cvs/apachen/STATUS,v retrieving revision 1.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- STATUS1997/12/26 18:16:14 1.30 +++ STATUS1997/12/26 18:21:43 1.31 @@ -54,9 +54,14 @@ * Dean's [PATCH] ap_snprintf should be more sane (fwd) * Jim's/Ken's move of main/util_snprintf.c to ap/ap_snprintf.c * [PATCH] Re: [BUGFIXES] Wrong GID for PID file and UMASK for logs +* Dean's [PATCH] fix Rasmus' chunking error Available: +* [PATCH] PR#1366: fix result of send_fd_length + [EMAIL PROTECTED] + Status: Dean +1, Dirk +1 + * Jim's [PATCH] ap_cpystrn() function (replace strncpy) [EMAIL PROTECTED] Status: Jim +1 @@ -68,10 +73,6 @@ * Ken's [PATCH] for PR#1195 ( in realm names) [EMAIL PROTECTED] Status: Ken +1, Dean +1, Jim +1 - -* Dean's [PATCH] fix Rasmus' chunking error - [EMAIL PROTECTED] - Status: Dean +1, Rasmus +1, Jim +1 * Dean's [PATCH] mod_status cleanups [EMAIL PROTECTED] 1.544 +6 -0 apachen/src/CHANGES Index: CHANGES === RCS file: /export/home/cvs/apachen/src/CHANGES,v retrieving revision 1.543 retrieving revision 1.544 diff -u -r1.543 -r1.544 --- CHANGES 1997/12/26 18:16:15 1.543 +++ CHANGES 1997/12/26 18:21:44 1.544 @@ -1,5 +1,11 @@ Changes with Apache 1.3b4 + *) The large_write() changes tickled a bug in bputc(), this would + show up as certain modules not working with Internet Explorer 4.0. + Fix this bug, and also fix a performance bug related to bputc() + causing a large_write() -- don't do large_write() unless there's + at least two bytes to write. [Dean Gaudet] + *) Move the gid switching code into the child so that log files and pid files are opened with the root gid. [Gregory A Lundberg [EMAIL PROTECTED]] 1.53 +13 -3 apachen/src/main/buff.c Index: buff.c === RCS file: /export/home/cvs/apachen/src/main/buff.c,v retrieving revision 1.52 retrieving revision 1.53 diff -u -r1.52 -r1.53 --- buff.c1997/12/23 02:03:54 1.52 +++ buff.c1997/12/26 18:21:46 1.53 @@ -807,9 +807,16 @@ API_EXPORT(int) bflsbuf(int c, BUFF *fb) { char ss[1]; +int rc; ss[0] = c; -return bwrite(fb, ss, 1); +rc = bwrite(fb, ss, 1); +/* We do start_chunk() here so that the bputc macro can be smaller + * and faster + */ +if (rc == 1 (fb-flags B_CHUNK)) + start_chunk(fb); +return rc; } /* @@ -1056,9 +1063,12 @@ #ifndef NO_WRITEV /* * Detect case where we're asked to write a large buffer, and combine our - * current buffer with it in a single writev() + * current buffer with it in a single writev(). Note we don't consider + * the case nbyte == 1 because modules which use rputc() loops will cause + * us to use writev() too frequently. In those cases we really should just + * start a new buffer. */ -if (fb-outcnt 0 nbyte + fb-outcnt = fb-bufsiz) { +if (fb-outcnt 0 nbyte 1 nbyte + fb-outcnt = fb-bufsiz) { return large_write(fb, buf, nbyte); } #endif
cvs commit: apachen/src/main buff.c
dgaudet 97/12/22 18:03:55 Modified:.STATUS src CHANGES src/main buff.c Log: remove some dead code Submitted by: Igor Tatarinov [EMAIL PROTECTED] Reviewed by: Dean Gaudet, Jim Jagielski Revision ChangesPath 1.18 +1 -4 apachen/STATUS Index: STATUS === RCS file: /export/home/cvs/apachen/STATUS,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- STATUS1997/12/23 01:51:26 1.17 +++ STATUS1997/12/23 02:03:51 1.18 @@ -49,6 +49,7 @@ * Dean's [PATCH] util_date.c needless reinitialization * Martin's [PATCH] Gimme a break! (missing break;s in mod_include) * Dean's [PATCH] two bugs in mod_autoindex +* Igor Tatarinov's Re: A tiny correction and a question on writev_it_all Available: @@ -58,10 +59,6 @@ * Dean's [PATCH] ap_snprintf should be more sane (fwd) [EMAIL PROTECTED] - Status: Dean +1, Jim +1 - -* Igor Tatarinov's Re: A tiny correction and a question on writev_it_all - [EMAIL PROTECTED] Status: Dean +1, Jim +1 * Dean's [PATCH] Re: [BUGFIXES] Wrong GID for PID file and UMASK for logs 1.537 +3 -0 apachen/src/CHANGES Index: CHANGES === RCS file: /export/home/cvs/apachen/src/CHANGES,v retrieving revision 1.536 retrieving revision 1.537 diff -u -r1.536 -r1.537 --- CHANGES 1997/12/23 01:50:00 1.536 +++ CHANGES 1997/12/23 02:03:52 1.537 @@ -1,4 +1,7 @@ Changes with Apache 1.3b4 + + *) Eliminate some dead code from writev_it_all(). + [Igor Tatarinov [EMAIL PROTECTED]] *) mod_autoindex had an fread() without checking the result code. It also wouldn't handle AddIconByType (TXT,/icons/text.gif text/* 1.52 +0 -3 apachen/src/main/buff.c Index: buff.c === RCS file: /export/home/cvs/apachen/src/main/buff.c,v retrieving revision 1.51 retrieving revision 1.52 diff -u -r1.51 -r1.52 --- buff.c1997/11/13 20:37:57 1.51 +++ buff.c1997/12/23 02:03:54 1.52 @@ -898,9 +898,6 @@ vec[i].iov_base = (char *) vec[i].iov_base + rv; vec[i].iov_len -= rv; rv = 0; - if (vec[i].iov_len == 0) { - ++i; - } } else { rv -= vec[i].iov_len;
cvs commit: apachen/src/main buff.c
ben 97/11/13 12:22:35 Modified:src CHANGES src/main buff.c Log: Fix Win32 16k bug. Revision ChangesPath 1.510 +4 -0 apachen/src/CHANGES Index: CHANGES === RCS file: /export/home/cvs/apachen/src/CHANGES,v retrieving revision 1.509 retrieving revision 1.510 diff -u -r1.509 -r1.510 --- CHANGES 1997/11/13 15:00:08 1.509 +++ CHANGES 1997/11/13 20:22:32 1.510 @@ -1,5 +1,9 @@ Changes with Apache 1.3b3 + *) Some Win32 systems terminated all responses after 16 kB. This turns + out to be a bug in Winsock - select() doesn't always return the + correct status. [Ben Laurie] + *) Directives owned by http_core can now use the new check_cmd_context() routine to ensure that they're not being used within a container (e.g., Directory) where they're invalid. [Martin Kraemer] 1.50 +34 -17apachen/src/main/buff.c Index: buff.c === RCS file: /export/home/cvs/apachen/src/main/buff.c,v retrieving revision 1.49 retrieving revision 1.50 diff -u -r1.49 -r1.50 --- buff.c1997/11/02 14:04:36 1.49 +++ buff.c1997/11/13 20:22:34 1.50 @@ -53,6 +53,7 @@ #include httpd.h #include http_main.h +#include http_log.h #include errno.h #include stdio.h @@ -98,6 +99,10 @@ #ifdef WIN32 +/* + select() sometimes returns 0 even though the timeout has _not_ expired. We must work around this. +*/ + int sendwithtimeout(int sock, const char *buf, int len, int flags) { int iostate = 1; @@ -105,6 +110,7 @@ struct timeval tv; int err = WSAEWOULDBLOCK; int rv; +int retry; if (!(tv.tv_sec = check_alarm())) return (send(sock, buf, len, flags)); @@ -118,25 +124,36 @@ rv = send(sock, buf, len, flags); if (rv == SOCKET_ERROR) { err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { - FD_ZERO(fdset); - FD_SET(sock, fdset); - tv.tv_usec = 0; - rv = select(FD_SETSIZE, NULL, fdset, NULL, tv); - if (rv == SOCKET_ERROR) - err = WSAGetLastError(); - else if (rv == 0) { - ioctlsocket(sock, FIONBIO, iostate); - check_alarm(); - WSASetLastError(WSAEWOULDBLOCK); - return (SOCKET_ERROR); - } - else { - rv = send(sock, buf, len, flags); + if (err == WSAEWOULDBLOCK) + do { + retry=0; + + FD_ZERO(fdset); + FD_SET(sock, fdset); + tv.tv_usec = 0; + rv = select(FD_SETSIZE, NULL, fdset, NULL, tv); if (rv == SOCKET_ERROR) err = WSAGetLastError(); - } - } + else if (rv == 0) { + ioctlsocket(sock, FIONBIO, iostate); + if(check_alarm() 0) { + WSASetLastError(EINTR); /* Simulate an alarm() */ + return (SOCKET_ERROR); + } + } + else { + rv = send(sock, buf, len, flags); + if (rv == SOCKET_ERROR) { + err = WSAGetLastError(); + if(err == WSAEWOULDBLOCK) { + aplog_error(APLOG_MARK,APLOG_WARNING,NULL, + select claimed we could write, but in fact we couldn't. This is a bug in Windows.); + retry=1; + Sleep(100); + } + } + } + } while(retry); } ioctlsocket(sock, FIONBIO, iostate); if (rv == SOCKET_ERROR)
cvs commit: apachen/src/main buff.c
ben 97/11/13 12:37:58 Modified:src/main buff.c Log: Correct the comment. Revision ChangesPath 1.51 +1 -1 apachen/src/main/buff.c Index: buff.c === RCS file: /export/home/cvs/apachen/src/main/buff.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- buff.c1997/11/13 20:22:34 1.50 +++ buff.c1997/11/13 20:37:57 1.51 @@ -100,7 +100,7 @@ #ifdef WIN32 /* - select() sometimes returns 0 even though the timeout has _not_ expired. We must work around this. + select() sometimes returns 1 even though the write will block. We must work around this. */ int sendwithtimeout(int sock, const char *buf, int len, int flags)
cvs commit: apachen/src/main buff.c
ben 97/11/02 06:04:37 Modified:src/main buff.c Log: Correct error checking in recvwithtimeout(). Revision ChangesPath 1.49 +8 -4 apachen/src/main/buff.c Index: buff.c === RCS file: /export/home/cvs/apachen/src/main/buff.c,v retrieving revision 1.48 retrieving revision 1.49 diff -u -r1.48 -r1.49 --- buff.c1997/11/01 21:13:20 1.48 +++ buff.c1997/11/02 14:04:36 1.49 @@ -167,15 +167,19 @@ FD_SET(sock, fdset); tv.tv_usec = 0; rv = select(FD_SETSIZE, fdset, NULL, NULL, tv); - if (rv == 0) { + if (rv == SOCKET_ERROR) + err = WSAGetLastError(); + else if (rv == 0) { ioctlsocket(sock, FIONBIO, iostate); check_alarm(); WSASetLastError(WSAEWOULDBLOCK); return (SOCKET_ERROR); } - rv = recv(sock, buf, len, flags); - if (rv == SOCKET_ERROR) - err = WSAGetLastError(); + else { + rv = recv(sock, buf, len, flags); + if (rv == SOCKET_ERROR) + err = WSAGetLastError(); + } } } ioctlsocket(sock, FIONBIO, iostate);
cvs commit: apachen/src/main buff.c buff.h
dgaudet 97/09/14 04:13:54 Modified:src INDENT src/main buff.c buff.h Log: indent Revision ChangesPath 1.7 +4 -4 apachen/src/INDENT Index: INDENT === RCS file: /export/home/cvs/apachen/src/INDENT,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- INDENT1997/09/14 11:09:32 1.6 +++ INDENT1997/09/14 11:13:51 1.7 @@ -3,10 +3,10 @@ If a file has already been indent'd, or doesn't need it, mark it as DONE ./main: STATUS - alloc.c - alloc.h - buff.cRESERVED by Dean - buff.hRESERVED by Dean + alloc.c RESERVED by Dean + alloc.h RESERVED by Dean + buff.cDONE by Dean + buff.hDONE by Dean conf.h dummy.c explain.c 1.45 +318 -300 apachen/src/main/buff.c Index: buff.c === RCS file: /export/home/cvs/apachen/src/main/buff.c,v retrieving revision 1.44 retrieving revision 1.45 diff -u -r1.44 -r1.45 --- buff.c1997/08/17 11:40:11 1.44 +++ buff.c1997/09/14 11:13:52 1.45 @@ -97,8 +97,7 @@ #ifdef WIN32 -int -sendwithtimeout(int sock, const char *buf, int len, int flags) +int sendwithtimeout(int sock, const char *buf, int len, int flags) { int iostate = 1; fd_set fdset; @@ -106,47 +105,42 @@ int err = WSAEWOULDBLOCK; int rv; -if(!(tv.tv_sec = check_alarm())) -return(send(sock, buf, len, flags)); - +if (!(tv.tv_sec = check_alarm())) + return (send(sock, buf, len, flags)); + rv = ioctlsocket(sock, FIONBIO, iostate); iostate = 0; -if(rv) -{ -err = WSAGetLastError(); -ap_assert(0); +if (rv) { + err = WSAGetLastError(); + ap_assert(0); } rv = send(sock, buf, len, flags); -if(rv == SOCKET_ERROR) -{ -err = WSAGetLastError(); -if(err == WSAEWOULDBLOCK) -{ -FD_ZERO(fdset); -FD_SET(sock, fdset); -tv.tv_usec = 0; -rv = select(FD_SETSIZE, NULL, fdset, NULL, tv); -if(rv == 0) -{ -ioctlsocket(sock, FIONBIO, iostate); -check_alarm(); -WSASetLastError(WSAEWOULDBLOCK); -return(SOCKET_ERROR); -} -rv = send(sock, buf, len, flags); -if(rv == SOCKET_ERROR) -err = WSAGetLastError(); -} +if (rv == SOCKET_ERROR) { + err = WSAGetLastError(); + if (err == WSAEWOULDBLOCK) { + FD_ZERO(fdset); + FD_SET(sock, fdset); + tv.tv_usec = 0; + rv = select(FD_SETSIZE, NULL, fdset, NULL, tv); + if (rv == 0) { + ioctlsocket(sock, FIONBIO, iostate); + check_alarm(); + WSASetLastError(WSAEWOULDBLOCK); + return (SOCKET_ERROR); + } + rv = send(sock, buf, len, flags); + if (rv == SOCKET_ERROR) + err = WSAGetLastError(); + } } ioctlsocket(sock, FIONBIO, iostate); -if(rv == SOCKET_ERROR) -WSASetLastError(err); -return(rv); +if (rv == SOCKET_ERROR) + WSASetLastError(err); +return (rv); } -int -recvwithtimeout(int sock, char *buf, int len, int flags) +int recvwithtimeout(int sock, char *buf, int len, int flags) { int iostate = 1; fd_set fdset; @@ -154,74 +148,71 @@ int err = WSAEWOULDBLOCK; int rv; -if(!(tv.tv_sec = check_alarm())) -return(recv(sock, buf, len, flags)); - +if (!(tv.tv_sec = check_alarm())) + return (recv(sock, buf, len, flags)); + rv = ioctlsocket(sock, FIONBIO, iostate); iostate = 0; ap_assert(!rv); rv = recv(sock, buf, len, flags); -if(rv == SOCKET_ERROR) -{ -err = WSAGetLastError(); -if(err == WSAEWOULDBLOCK) -{ -FD_ZERO(fdset); -FD_SET(sock, fdset); -tv.tv_usec = 0; -rv = select(FD_SETSIZE, fdset, NULL, NULL, tv); -if(rv == 0) -{ -ioctlsocket(sock, FIONBIO, iostate); -check_alarm(); -WSASetLastError(WSAEWOULDBLOCK); -return(SOCKET_ERROR); -} -rv = recv(sock, buf, len, flags); -if(rv == SOCKET_ERROR) -err = WSAGetLastError(); -} +if (rv == SOCKET_ERROR) { + err = WSAGetLastError(); + if (err == WSAEWOULDBLOCK) { +