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)