ben 97/11/13 12:22:35
Modified: src CHANGES src/main buff.c Log: Fix Win32 16k bug. Revision Changes Path 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 -17 apachen/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.c 1997/11/02 14:04:36 1.49 +++ buff.c 1997/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)