You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by st...@hyperreal.org on 1999/10/22 07:10:09 UTC

cvs commit: apache-1.3/src/main buff.c

stoddard    99/10/21 22:10:09

  Modified:    src/main buff.c
  Log:
  Apache for Windows can get caught in a tight loop whild handling CGI requests. Here's how:
  sendwithtimeout() sets  errno to EINTR on a timeout and returns SOCKET_ERROR (-1) to
  the caller. The caller reissues sendwithtimeout, which then succeeds. errno is left set to
  EINTR. Eventually,  another read is attempted on one of the CGI pipes (ap_bgets in mod_cgi,
  or ap_send_fb_length) which goes down into ap_read. ap_read issues a Win32 ReadFile to read
  from the pipe. If this read fails, it returns -1 to the caller. If errno
  is still set to EINTR, the caller will retry the read and so the loop begins.
  
  The solution is quite simple. buff.c relies heavily on errno. Anytime Win32 calls are used
  in code that uses errno, we need to always, ALWAYS explicitly set errno when a Win32 system
  call fails (via either errno = GetLastError() or errno = WSAGetLastError()). Since Win32
  does not use EINTR, this problem should not occur.
  
  PR: 3599 3971 4245 4430 4758 5171
  Submitted by:	Thanks to Jim.Patterson@cognos.com who discovered the loopig section of
  code.
  
  Revision  Changes    Path
  1.90      +19 -15    apache-1.3/src/main/buff.c
  
  Index: buff.c
  ===================================================================
  RCS file: /home/cvs/apache-1.3/src/main/buff.c,v
  retrieving revision 1.89
  retrieving revision 1.90
  diff -u -r1.89 -r1.90
  --- buff.c	1999/10/21 20:44:32	1.89
  +++ buff.c	1999/10/22 05:10:06	1.90
  @@ -172,12 +172,12 @@
   			    
   			    retry=1;
   #ifdef NETWARE
  -                ap_log_error(APLOG_MARK,APLOG_DEBUG,NULL,
  -				    "select claimed we could write, but in fact we couldn't.");
  -				ThreadSwitchWithDelay();
  +                            ap_log_error(APLOG_MARK,APLOG_DEBUG,NULL,
  +                                         "select claimed we could write, but in fact we couldn't.");
  +                            ThreadSwitchWithDelay();
   #else
  -                ap_log_error(APLOG_MARK,APLOG_DEBUG,NULL,
  -				    "select claimed we could write, but in fact we couldn't. This is a bug in Windows.");
  +                            ap_log_error(APLOG_MARK,APLOG_DEBUG,NULL,
  +                                         "select claimed we could write, but in fact we couldn't. This is a bug in Windows.");
   			    Sleep(100);
   #endif
   			}
  @@ -250,8 +250,10 @@
       
   #ifdef WIN32
       if (fb->hFH != INVALID_HANDLE_VALUE) {
  -        if (!ReadFile(fb->hFH,buf,nbyte,&rv,NULL))
  +        if (!ReadFile(fb->hFH,buf,nbyte,&rv,NULL)) {
  +            errno = GetLastError();
               rv = -1;
  +        }
       }
       else
   #endif
  @@ -274,9 +276,9 @@
   	rv = ap_read(fb, buf, nbyte);
   #elif defined (BEOS)
       if (fb->flags & B_SOCKET) {
  -    rv = recv(fb->fd_in, buf, nbyte, 0);
  +        rv = recv(fb->fd_in, buf, nbyte, 0);
       } else
  -    rv = ap_read(fb,buf,nbyte);
  +        rv = ap_read(fb,buf,nbyte);
   #elif defined(TPF)
       fd_set fds;
       struct timeval tv;
  @@ -293,7 +295,7 @@
               rv = ap_read(fb, buf, nbyte);
       }
       else
  -    rv = ap_read(fb, buf, nbyte);
  +        rv = ap_read(fb, buf, nbyte);
   #else
       rv = ap_read(fb, buf, nbyte);
   #endif /* WIN32 */
  @@ -307,8 +309,10 @@
       
   #ifdef WIN32
       if (fb->hFH != INVALID_HANDLE_VALUE) {
  -        if (!WriteFile(fb->hFH,buf,nbyte,&rv,NULL))
  -          rv = -1;
  +        if (!WriteFile(fb->hFH,buf,nbyte,&rv,NULL)) {
  +            errno = GetLastError();
  +            rv = -1;
  +        }
       }
       else
   #endif
  @@ -335,9 +339,9 @@
   	rv = ap_write(fb, buf, nbyte);
   #elif defined(BEOS)
       if(fb->flags & B_SOCKET) {
  -    rv = send(fb->fd, buf, nbyte, 0);
  +        rv = send(fb->fd, buf, nbyte, 0);
       } else 
  -    rv = ap_write(fb, buf,nbyte);
  +        rv = ap_write(fb, buf,nbyte);
   #else
       rv = ap_write(fb, buf, nbyte);
   #endif /* WIN32 */
  @@ -1457,8 +1461,8 @@
       }
   #ifndef NETWARE
       else if (fb->hFH != INVALID_HANDLE_VALUE) {
  -	    rc2 = ap_pcloseh(fb->pool, fb->hFH);
  -	    rc3 = 0;
  +        rc2 = ap_pcloseh(fb->pool, fb->hFH);
  +        rc3 = 0;
       }
   #endif
       else {