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)
  
  
  

Reply via email to