You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rb...@locus.apache.org on 2000/05/24 21:19:24 UTC

cvs commit: apache-2.0/src/os/unix iol_socket.c

rbb         00/05/24 12:19:23

  Modified:    .        STATUS
               src      CHANGES
               src/include ap_iol.h buff.h
               src/lib/apr/file_io/unix readwrite.c
               src/lib/apr/include apr_file_io.h
               src/main buff.c http_protocol.c iol_file.c
               src/os/unix iol_socket.c
  Log:
  Implement saferead in Apache 2.0.  This has had minimal testing, and it
  seems to work, but only really hammering on it will tell for sure.
  
  Revision  Changes    Path
  1.67      +1 -4      apache-2.0/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /home/cvs/apache-2.0/STATUS,v
  retrieving revision 1.66
  retrieving revision 1.67
  diff -u -r1.66 -r1.67
  --- STATUS	2000/05/23 21:50:57	1.66
  +++ STATUS	2000/05/24 19:18:57	1.67
  @@ -1,5 +1,5 @@
   Apache 2.0 STATUS:
  -Last modified at [$Date: 2000/05/23 21:50:57 $]
  +Last modified at [$Date: 2000/05/24 19:18:57 $]
   
   Release:
   
  @@ -22,9 +22,6 @@
               default cgi module on Unix with a threaded MPM is the cgid
               module.  This should be override-able of course.
             Status: Jim Jagielski is looking into this.
  -
  -    * Fix SAFEREAD.
  -	see <Pi...@twinlark.arctic.org>
   
       * Put back resource limit code
   
  
  
  
  1.119     +4 -0      apache-2.0/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/CHANGES,v
  retrieving revision 1.118
  retrieving revision 1.119
  diff -u -r1.118 -r1.119
  --- CHANGES	2000/05/24 11:45:44	1.118
  +++ CHANGES	2000/05/24 19:19:03	1.119
  @@ -1,5 +1,9 @@
   Changes with Apache 2.0a4
   
  +  *) Fix saferead.  Basically, we flush the output buffer if a read on the
  +     input will block.
  +     [Ryan Bloom]
  + 
     *) APR: Add ap_xlate_get_sb() so that an app can find out whether or not
        a conversion is single-byte only. [Jeff Trawick]
   
  
  
  
  1.18      +2 -0      apache-2.0/src/include/ap_iol.h
  
  Index: ap_iol.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/ap_iol.h,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- ap_iol.h	2000/04/13 23:51:13	1.17
  +++ ap_iol.h	2000/05/24 19:19:04	1.18
  @@ -118,6 +118,7 @@
                                ap_off_t * offset, ap_size_t * len, 
                                ap_int32_t flags);
       ap_status_t (*shutdown)(ap_iol *fd, int how);
  +    ap_status_t (*check_read)(ap_iol *fd);
       /* TODO: accept, connect, ... */
   };
   
  @@ -136,6 +137,7 @@
   #define iol_getopt(iol, a, b) ((iol)->methods->getopt((iol), (a), (b)))
   #define iol_sendfile(iol, a, b, c, d, e) ((iol)->methods->sendfile((iol), (a), (b), (c), (d), (e)))
   #define iol_shutdown(iol, a) ((iol)->methods->shutdown((iol), (a)))
  +#define iol_check_read(iol) ((iol)->methods->check_read((iol)))
   
   /* the file iol */
   ap_iol *ap_create_file_iol(ap_file_t *file);
  
  
  
  1.22      +1 -1      apache-2.0/src/include/buff.h
  
  Index: buff.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/buff.h,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- buff.h	2000/05/12 15:47:07	1.21
  +++ buff.h	2000/05/24 19:19:04	1.22
  @@ -124,7 +124,7 @@
   /* Use chunked writing */
   #define B_CHUNK (64)
   /* bflush() if a read would block */
  -/* TODO: #define B_SAFEREAD (128) */
  +#define B_SAFEREAD (128)
   /* caller expects non-blocking behaviour */
   #define B_NONBLOCK (512)
   
  
  
  
  1.47      +18 -0     apache-2.0/src/lib/apr/file_io/unix/readwrite.c
  
  Index: readwrite.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/unix/readwrite.c,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- readwrite.c	2000/04/28 18:27:37	1.46
  +++ readwrite.c	2000/05/24 19:19:16	1.47
  @@ -412,3 +412,21 @@
       return (cc == APR_SUCCESS) ? len : -1;
   }
   
  +ap_status_t ap_file_check_read(ap_file_t *fd)
  +{
  +    fd_set fds;
  +    int rv;
  +    struct timeval tv;
  +
  +    FD_ZERO(&fds);
  +    FD_SET(fd->filedes, &fds);
  +    tv.tv_sec = 0;
  +    tv.tv_usec = 0;
  +    if (rv = select(fd->filedes + 1, &fds, NULL, NULL, &tv) == -1) {
  +        return errno;
  +    }
  +    else {
  +        return rv;
  +    }
  +}
  +
  
  
  
  1.47      +12 -0     apache-2.0/src/lib/apr/include/apr_file_io.h
  
  Index: apr_file_io.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_file_io.h,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- apr_file_io.h	2000/04/28 02:35:39	1.46
  +++ apr_file_io.h	2000/05/24 19:19:18	1.47
  @@ -253,6 +253,18 @@
   
   /*
   
  +=head1 ap_status_t ap_file_check_read(ap_file_t *fd)
  +
  +B<Determine if the next read will block.>
  +
  +    arg 1) The file descriptor to check.
  +
  +=cut
  + */
  +ap_status_t ap_file_check_read(ap_file_t *fd);
  +
  +/*
  +
   =head1 ap_status_t ap_write(ap_file_t *thefile, void *buf, ap_ssize_t *nbytes)
   
   B<Write data to the specified file.>
  
  
  
  1.42      +34 -1     apache-2.0/src/main/buff.c
  
  Index: buff.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/buff.c,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- buff.c	2000/05/15 17:51:21	1.41
  +++ buff.c	2000/05/24 19:19:19	1.42
  @@ -396,6 +396,39 @@
       return value;
   }
   
  +static void ap_bhalfduplex(BUFF *fb)
  +{
  +    int rv;
  +    /* There is nothing to do if the there is something readable in the 
  +     * incoming buffer or there is nothing flushable in the output buffer.
  +     */
  +    if (fb == NULL || fb->incnt > 0 || fb->outcnt == 0) {
  +        return;
  +    }
  +    /* test for a block */
  +    do {
  +        rv = iol_check_read(fb->iol);
  +    } while (rv == APR_EINTR && !(fb->flags & B_EOUT));
  +
  +    /* treat any error as if it would block as well */ 
  +    if (rv != APR_SUCCESS) {
  +        ap_bflush(fb);
  +    } 
  +}
  +
  +static ap_inline ap_status_t saferead(BUFF *fb, void *buf, ap_size_t nbyte,
  +                                      ap_ssize_t *bytes_read)
  +{
  +    ap_status_t rv;
  + 
  +    if (fb->flags & B_SAFEREAD) {
  +        ap_bhalfduplex(fb);
  +    }
  +    do {
  +        rv = iol_read(fb->iol, buf, nbyte, bytes_read);
  +    } while (rv == EINTR && !(fb->flags &B_EOUT));
  +    return rv;
  +}
   
   /* a wrapper around iol_read which checks for errors and EOFs */
   static ap_status_t read_with_errors(BUFF *fb, void *buf, ap_size_t nbyte,
  @@ -403,7 +436,7 @@
   {
       ap_status_t rv;
   
  -    rv = iol_read(fb->iol, buf, nbyte, bytes_read);
  +    rv = saferead(fb, buf, nbyte, bytes_read);
       if (rv == APR_SUCCESS && *bytes_read == 0) {
   	fb->flags |= B_EOF;
       }
  
  
  
  1.69      +3 -4      apache-2.0/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v
  retrieving revision 1.68
  retrieving revision 1.69
  diff -u -r1.68 -r1.69
  --- http_protocol.c	2000/05/17 03:19:38	1.68
  +++ http_protocol.c	2000/05/24 19:19:20	1.69
  @@ -866,12 +866,11 @@
        * read().  B_SAFEREAD ensures that the BUFF layer flushes if it will
        * have to block during a read.
        */
  -    /* TODO: reimplement SAFEREAD external to BUFF using a layer */
  -    /* //ap_bsetflag(conn->client, B_SAFEREAD, 1); */
  +    ap_bsetflag(conn->client, B_SAFEREAD, 1); 
       ap_bflush(conn->client);
       while ((len = getline(l, sizeof(l), conn->client, 0)) <= 0) {
           if ((len < 0) || ap_bgetflag(conn->client, B_EOF)) {
  -	    /* //ap_bsetflag(conn->client, B_SAFEREAD, 0); */
  +	    ap_bsetflag(conn->client, B_SAFEREAD, 0);
   	    /* this is a hack to make sure that request time is set,
   	     * it's not perfect, but it's better than nothing 
   	     */
  @@ -892,7 +891,7 @@
   #endif
       */
   
  -    /* //ap_bsetflag(conn->client, B_SAFEREAD, 0); */
  +    ap_bsetflag(conn->client, B_SAFEREAD, 0);
   
       r->request_time = ap_now();
       r->the_request = ap_pstrdup(r->pool, l);
  
  
  
  1.16      +8 -2      apache-2.0/src/main/iol_file.c
  
  Index: iol_file.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/iol_file.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- iol_file.c	2000/04/15 02:56:47	1.15
  +++ iol_file.c	2000/05/24 19:19:20	1.16
  @@ -123,13 +123,20 @@
       return APR_EINVAL;
   }
   
  +static ap_status_t file_check_read(ap_iol *viol)
  +{
  +    iol_file *iol = (iol_file *)viol;
  +    return ap_file_check_read(iol->file);
  +}
  +
   static const ap_iol_methods file_methods = {
       file_close,
       file_ap_write,
       file_ap_writev,
       file_ap_read,
       file_setopt,
  -    file_getopt
  +    file_getopt,
  +    file_check_read
   };
   
   /*
  @@ -143,4 +150,3 @@
       iol->file = file;
       return (ap_iol *)iol;
   }
  -
  
  
  
  1.22      +2 -1      apache-2.0/src/os/unix/iol_socket.c
  
  Index: iol_socket.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/os/unix/iol_socket.c,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- iol_socket.c	2000/04/16 16:59:40	1.21
  +++ iol_socket.c	2000/05/24 19:19:23	1.22
  @@ -150,7 +150,8 @@
       unix_setopt,
       unix_getopt,
       NULL,
  -    unix_shutdown
  +    unix_shutdown,
  +    NULL,
   };
   
   ap_iol *unix_attach_socket(ap_socket_t *sock)