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)