You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by br...@apache.org on 2005/10/06 08:13:41 UTC

svn commit: r306540 - /httpd/httpd/branches/async-dev/server/connection.c

Author: brianp
Date: Wed Oct  5 23:13:39 2005
New Revision: 306540

URL: http://svn.apache.org/viewcvs?rev=306540&view=rev
Log:
port the fix for PR35292 forward from the 2.3 trunk to the async-dev branch, because one of the perl-framework test cases now checks for this fix

Modified:
    httpd/httpd/branches/async-dev/server/connection.c

Modified: httpd/httpd/branches/async-dev/server/connection.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/async-dev/server/connection.c?rev=306540&r1=306539&r2=306540&view=diff
==============================================================================
--- httpd/httpd/branches/async-dev/server/connection.c (original)
+++ httpd/httpd/branches/async-dev/server/connection.c Wed Oct  5 23:13:39 2005
@@ -98,10 +98,8 @@
 AP_DECLARE(void) ap_lingering_close(conn_rec *c)
 {
     char dummybuf[512];
-    apr_size_t nbytes = sizeof(dummybuf);
-    apr_status_t rc;
-    apr_int32_t timeout;
-    apr_int32_t total_linger_time = 0;
+    apr_size_t nbytes;
+    apr_time_t timeup = 0;
     apr_socket_t *csd = ap_get_module_config(c->conn_config, &core_module);
 
     if (!csd) {
@@ -138,25 +136,29 @@
         return;
     }
 
-    /* Read all data from the peer until we reach "end-of-file" (FIN
-     * from peer) or we've exceeded our overall timeout. If the client does
-     * not send us bytes within 2 seconds (a value pulled from Apache 1.3
-     * which seems to work well), close the connection.
+    /* Read available data from the client whilst it continues sending
+     * it, for a maximum time of MAX_SECS_TO_LINGER.  If the client
+     * does not send any data within 2 seconds (a value pulled from
+     * Apache 1.3 which seems to work well), give up.
      */
-    timeout = apr_time_from_sec(SECONDS_TO_LINGER);
-    apr_socket_timeout_set(csd, timeout);
+    apr_socket_timeout_set(csd, apr_time_from_sec(SECONDS_TO_LINGER));
     apr_socket_opt_set(csd, APR_INCOMPLETE_READ, 1);
-    while (1) {
+
+    /* The common path here is that the initial apr_socket_recv() call
+     * will return 0 bytes read; so that case must avoid the expensive
+     * apr_time_now() call and time arithmetic. */
+
+    do {
         nbytes = sizeof(dummybuf);
-        rc = apr_socket_recv(csd, dummybuf, &nbytes);
-        if (rc != APR_SUCCESS || nbytes == 0)
+        if (apr_socket_recv(csd, dummybuf, &nbytes) || nbytes == 0)
             break;
 
-        total_linger_time += SECONDS_TO_LINGER;
-        if (total_linger_time >= MAX_SECS_TO_LINGER) {
-            break;
+        if (timeup == 0) {
+            /* First time through; calculate now + 30 seconds. */
+            timeup = apr_time_now() + apr_time_from_sec(MAX_SECS_TO_LINGER);
+            continue;
         }
-    }
+    } while (apr_time_now() < timeup);
 
     apr_socket_close(csd);
     return;