From: Brian Pane Date: Thu, 6 Oct 2005 06:13:39 +0000 (+0000) Subject: port the fix for PR35292 forward from the 2.3 trunk to the async-dev branch, because... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=846cbeee1c3ab5a81c6302340eff40439c477278;p=thirdparty%2Fapache%2Fhttpd.git 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 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/async-dev@306540 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/connection.c b/server/connection.c index 9f594979100..751892f486b 100644 --- a/server/connection.c +++ b/server/connection.c @@ -98,10 +98,8 @@ AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c) 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 @@ AP_DECLARE(void) ap_lingering_close(conn_rec *c) 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;