apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dean gaudet <d...@arctic.org>
Subject Re: Extraneous socket read?
Date Sat, 07 Jul 2001 18:23:42 GMT
On Mon, 2 Jul 2001, Brian Pane wrote:

> >On Mon, 2 Jul 2001, Brian Pane wrote:
> >
> >>then it should be possible to eliminate a system call by not doing the
> >>initial read before the select.
> >>
> Here's a patch that disables the read before the select, but only for
> the HTTP client socket.

hey brian, i think i prefer the approach below instead.  but i haven't
been able to test this patch because my top-of-tree httpd-2.0 won't build
with top-of-tree apr/apr-util.

the approach i'm using doesn't require any changes to any applications --
it just implements the heuristic i mentioned earlier.  whenever a read()
returns an incomplete buffer assume we want to select() first before
read()ing again (and all of this only if the socket is non-blocking).

-dean

Index: srclib/apr/include/apr_network_io.h
===================================================================
RCS file: /home/cvs/apr/include/apr_network_io.h,v
retrieving revision 1.102
diff -u -r1.102 apr_network_io.h
--- srclib/apr/include/apr_network_io.h	2001/05/02 02:32:44	1.102
+++ srclib/apr/include/apr_network_io.h	2001/07/07 18:18:14
@@ -102,6 +102,12 @@
                                    * APR_TCP_NODELAY should be turned on
                                    * again when NOPUSH is turned off
                                    */
+/* an internal flag.  this is set on non-blocking sockets
+ * (APR_SO_TIMEOUT != 0) on which the previous read() did not fill a
+ * buffer completely.  the next apr_recv() will first call select()/poll()
+ * rather than going straight into read().
+ */
+#define APR_INCOMPLETE_READ 4096

 #define APR_POLLIN    0x001
 #define APR_POLLPRI   0x002
Index: srclib/apr/network_io/unix/sendrecv.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sendrecv.c,v
retrieving revision 1.65
diff -u -r1.65 sendrecv.c
--- srclib/apr/network_io/unix/sendrecv.c	2001/05/03 22:38:00	1.65
+++ srclib/apr/network_io/unix/sendrecv.c	2001/07/07 18:18:16
@@ -125,14 +125,21 @@
 apr_status_t apr_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
 {
     ssize_t rv;
-
+    apr_status_t arv;
+
+    if (sock->netmask & APR_INCOMPLETE_READ) {
+	sock->netmask &= ~APR_INCOMPLETE_READ;
+    	goto do_select;
+    }
+
     do {
-        rv = read(sock->socketdes, buf, (*len));
+	    rv = read(sock->socketdes, buf, (*len));
     } while (rv == -1 && errno == EINTR);

     if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
       sock->timeout != 0) {
-        apr_status_t arv = wait_for_io_or_timeout(sock, 1);
+do_select:
+        arv = wait_for_io_or_timeout(sock, 1);
         if (arv != APR_SUCCESS) {
             *len = 0;
             return arv;
@@ -146,6 +153,9 @@
     if (rv == -1) {
         (*len) = 0;
         return errno;
+    }
+    if (sock->timeout && rv < *len) {
+	sock->netmask |= APR_INCOMPLETE_READ;
     }
     (*len) = rv;
     if (rv == 0) {
Index: srclib/apr/network_io/unix/sockopt.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sockopt.c,v
retrieving revision 1.45
diff -u -r1.45 sockopt.c
--- srclib/apr/network_io/unix/sockopt.c	2001/04/05 18:56:08	1.45
+++ srclib/apr/network_io/unix/sockopt.c	2001/07/07 18:18:17
@@ -216,6 +216,12 @@
                 }
             }
         }
+	/* must disable the incomplete read support if we change to a
+	 * blocking socket.
+	 */
+	if (on == 0) {
+	    sock->netmask &= ~APR_INCOMPLETE_READ;
+	}
         sock->timeout = on;
         apr_set_option(&sock->netmask, APR_SO_TIMEOUT, on);
     }


Mime
View raw message