rbb         99/11/10 07:49:57

  Modified:    src/lib/apr/file_io/unix fileio.h open.c pipe.c readwrite.c
               src/lib/apr/include apr_file_io.h
               src/lib/apr/network_io/unix sendrecv.c sockopt.c
  Log:
  Add timeouts to pipes.  I also fixed a minor bug in timeout code for sending
  and receiving data over the network.  Specifying a negative timeout will
  result in the send or recv blocking until the operation is done.
  
  Revision  Changes    Path
  1.4       +1 -0      apache-2.0/src/lib/apr/file_io/unix/fileio.h
  
  Index: fileio.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/unix/fileio.h,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- fileio.h  1999/10/12 20:00:30     1.3
  +++ fileio.h  1999/11/10 15:49:53     1.4
  @@ -85,6 +85,7 @@
       time_t atime;
       time_t mtime;
       time_t ctime;
  +    int timeout;
   };
   
   struct dir_t {
  
  
  
  1.22      +7 -0      apache-2.0/src/lib/apr/file_io/unix/open.c
  
  Index: open.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/unix/open.c,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- open.c    1999/11/04 22:04:16     1.21
  +++ open.c    1999/11/10 15:49:53     1.22
  @@ -177,6 +177,7 @@
       }
   
       (*new)->stated = 0;  /* we haven't called stat for this file yet. */
  +    (*new)->timeout = -1;
       (*new)->eof_hit = 0;
       ap_register_cleanup((*new)->cntxt, (void *)(*new), file_cleanup,
                           ap_null_cleanup);
  @@ -257,6 +258,12 @@
           (*file) = ap_pcalloc(cont, sizeof(struct file_t));
           (*file)->cntxt = cont;
       }
  +    /* if we are putting in a new file descriptor, then we don't really
  +     * have any of this information.
  +     */
  +    (*file)->eof_hit = 0;
  +    (*file)->timeout = -1;
  +    (*file)->stated = 0;
       (*file)->filedes = *dafile;
       return APR_SUCCESS;
   }    
  
  
  
  1.5       +44 -0     apache-2.0/src/lib/apr/file_io/unix/pipe.c
  
  Index: pipe.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/unix/pipe.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- pipe.c    1999/11/01 03:07:07     1.4
  +++ pipe.c    1999/11/10 15:49:53     1.5
  @@ -63,7 +63,46 @@
   #include <sys/types.h>
   #include <sys/stat.h>
   
  +static ap_status_t pipenonblock(struct file_t *thefile)
  +{
  +    int fd_flags;
  +
  +    fd_flags = fcntl(thefile->filedes, F_GETFL, 0);
  +#if defined(O_NONBLOCK)
  +    fd_flags |= O_NONBLOCK;
  +#elif defined(O_NDELAY)
  +    fd_flags |= O_NDELAY;
  +#elif defined(FNDELAY)
  +    fd_flags |= O_FNDELAY;
  +#else
  +    /* XXXX: this breaks things, but an alternative isn't obvious...*/
  +    return -1;
  +#endif
  +    if (fcntl(thefile->filedes, F_SETFL, fd_flags) == -1) {
  +        return errno;
  +    }
  +    return APR_SUCCESS;
  +}
  +
   /* ***APRDOC********************************************************
  + * ap_status_t ap_set_pipe_timeout(ap_file_t *, ap_int32_t)
  + *    Set the timeout value for a pipe.
  + * arg 1) The pipe we are setting a timeout on.
  + * arg 3) The timeout value in seconds.  Values < 0 mean wait forever, 0
  + *        means do not wait at all.
  + */
  +ap_status_t ap_set_pipe_timeout(struct file_t *thepipe, ap_int32_t timeout)
  +{
  +    if (!strcmp(thepipe->fname, "PIPE")) {
  +        thepipe->timeout = timeout;
  +        return APR_SUCCESS;
  +    }
  +    return APR_EINVAL;
  +}
  +
  +
  +
  +/* ***APRDOC********************************************************
    * ap_status_t ap_create_pipe(ap_file_t **, ap_context_t *, ap_file_t **)
    *    Create an anonymous pipe.
    * arg 1) The context to operate on.
  @@ -83,12 +122,17 @@
       (*in)->filedes = filedes[0];
       (*in)->buffered = 0;
       (*in)->fname = ap_pstrdup(cont, "PIPE");
  +    (*in)->timeout = -1;
   
       (*out) = (struct file_t *)ap_palloc(cont, sizeof(struct file_t));
       (*out)->cntxt = cont;
       (*out)->filedes = filedes[1];
       (*out)->buffered = 0;
       (*out)->fname = ap_pstrdup(cont, "PIPE");
  +    (*out)->timeout = -1;
  +
  +    pipenonblock(*in);
  +    pipenonblock(*out);
   
       return APR_SUCCESS;
   }
  
  
  
  1.16      +81 -4     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.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- readwrite.c       1999/11/04 07:24:23     1.15
  +++ readwrite.c       1999/11/10 15:49:53     1.16
  @@ -70,6 +70,9 @@
   #ifdef HAVE_SYS_UIO_H
   #include <sys/uio.h>
   #endif
  +#ifdef HAVE_SYS_TIME_H
  +#include <sys/time.h>
  +#endif
   
   /* ***APRDOC********************************************************
    * ap_status_t ap_read(ap_file_t *, void *, ap_ssize_t *)
  @@ -95,8 +98,45 @@
           rv = fread(buf, *nbytes, 1, thefile->filehand);
       }
       else {
  -        rv = read(thefile->filedes, buf, *nbytes);
  -    }
  +        do {
  +            rv = read(thefile->filedes, buf, *nbytes);
  +        } while (rv == -1 && errno == EINTR);
  +
  +        if (rv == -1 && errno == EAGAIN && thefile->timeout != 0) {
  +            struct timeval *tv;
  +            fd_set fdset;
  +            int srv;
  +
  +            do {
  +                FD_ZERO(&fdset);
  +                FD_SET(thefile->filedes, &fdset);
  +                if (thefile->timeout == -1) {
  +                    tv = NULL;
  +                }
  +                else {
  +                    tv = ap_palloc(thefile->cntxt, sizeof(struct timeval));
  +                    tv->tv_sec  = thefile->timeout;
  +                    tv->tv_usec = 0;
  +                }
  +
  +                srv = select(FD_SETSIZE, &fdset, NULL, NULL, tv);
  +            } while (srv == -1 && errno == EINTR);
  +
  +            if (srv == 0) {
  +                (*nbytes) = -1;
  +                return APR_TIMEUP;
  +            }
  +            else if (srv < 0) {
  +                (*nbytes) = -1;
  +                return errno;
  +            }
  +            else {
  +                do {
  +                    rv = read(thefile->filedes, buf, *nbytes);
  +                } while (rv == -1 && errno == EINTR);
  +            }
  +        }  
  +    }  /* buffered? */
   
       if ((*nbytes != rv) && (errno != EINTR) && !thefile->buffered) {
           thefile->eof_hit = 1;
  @@ -132,8 +172,45 @@
           rv = fwrite(buf, *nbytes, 1, thefile->filehand);
       }
       else {
  -        rv = write(thefile->filedes, buf, *nbytes);
  -    }
  +        do {
  +            rv = write(thefile->filedes, buf, *nbytes);
  +        } while (rv == -1 && errno == EINTR);
  +
  +        if (rv == -1 && errno == EAGAIN && thefile->timeout != 0) {
  +            struct timeval *tv;
  +            fd_set fdset;
  +            int srv;
  +
  +            do {
  +                FD_ZERO(&fdset);
  +                FD_SET(thefile->filedes, &fdset);
  +                if (thefile->timeout == -1) {
  +                    tv = NULL;
  +                }
  +                else {
  +                    tv = ap_palloc(thefile->cntxt, sizeof(struct timeval));
  +                    tv->tv_sec  = thefile->timeout;
  +                    tv->tv_usec = 0;
  +                }
  +
  +                srv = select(FD_SETSIZE, NULL, &fdset, NULL, tv);
  +            } while (srv == -1 && errno == EINTR);
  +
  +            if (srv == 0) {
  +                (*nbytes) = -1;
  +                return APR_TIMEUP;
  +            }
  +            else if (srv < 0) {
  +                (*nbytes) = -1;
  +                return errno;
  +            }
  +            else {
  +                do {
  +                    rv = write(thefile->filedes, buf, *nbytes);
  +                } while (rv == -1 && errno == EINTR);
  +            }
  +        }  
  +    }   /* BUFFERED ?? */
   
       thefile->stated = 0;
       *nbytes = rv;
  
  
  
  1.18      +1 -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.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- apr_file_io.h     1999/10/15 14:19:56     1.17
  +++ apr_file_io.h     1999/11/10 15:49:55     1.18
  @@ -144,6 +144,7 @@
   
   ap_status_t ap_create_pipe(ap_file_t **, ap_file_t **, ap_context_t *);
   ap_status_t ap_create_namedpipe(char **, char *, ap_fileperms_t, 
ap_context_t *);
  +ap_status_t ap_set_pipe_timeout(ap_file_t *thepipe, ap_int32_t timeout);
   
   /*accessor and general file_io functions. */
   ap_status_t ap_get_filename(char **, ap_file_t *);
  
  
  
  1.4       +4 -4      apache-2.0/src/lib/apr/network_io/unix/sendrecv.c
  
  Index: sendrecv.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sendrecv.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- sendrecv.c        1999/09/03 14:20:23     1.3
  +++ sendrecv.c        1999/11/10 15:49:55     1.4
  @@ -80,7 +80,7 @@
           rv = write(sock->socketdes, buf, (*len));
       } while (rv == -1 && errno == EINTR);
   
  -    if (rv == -1 && errno == EAGAIN && sock->timeout > 0) {
  +    if (rv == -1 && errno == EAGAIN && sock->timeout != 0) {
           struct timeval *tv;
           fd_set fdset;
           int srv;
  @@ -88,7 +88,7 @@
           do {
               FD_ZERO(&fdset);
               FD_SET(sock->socketdes, &fdset);
  -            if (sock->timeout== -1) {
  +            if (sock->timeout < 0) {
                   tv = NULL;
               }
               else {
  @@ -135,7 +135,7 @@
           rv = read(sock->socketdes, buf, (*len));
       } while (rv == -1 && errno == EINTR);
   
  -    if (rv == -1 && errno == EAGAIN && sock->timeout > 0) {
  +    if (rv == -1 && errno == EAGAIN && sock->timeout != 0) {
           struct timeval *tv;
           fd_set fdset;
           int srv;
  @@ -143,7 +143,7 @@
           do {
               FD_ZERO(&fdset);
               FD_SET(sock->socketdes, &fdset);
  -            if (sock->timeout == -1) {
  +            if (sock->timeout < 0) {
                   tv = NULL;
               }
               else {
  
  
  
  1.12      +3 -1      apache-2.0/src/lib/apr/network_io/unix/sockopt.c
  
  Index: sockopt.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sockopt.c,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- sockopt.c 1999/10/24 05:59:15     1.11
  +++ sockopt.c 1999/11/10 15:49:55     1.12
  @@ -121,7 +121,9 @@
    *                                  supplied to bind should allow reuse
    *                                  of local addresses.
    *            APR_SO_TIMEOUT    --  Set the timeout value in seconds.
  - *            APR_SO_SNDBUF     -- Set the SendBufferSize
  + *                                  values < 0 mean wait forever.  0 means
  + *                                  don't wait at all.
  + *            APR_SO_SNDBUF     --  Set the SendBufferSize
    * arg 3) Are we turning the option on or off.
    */
   ap_status_t ap_setsocketopt(struct socket_t *sock, ap_int32_t opt, 
ap_int32_t on)
  
  
  

Reply via email to