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)