summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Stoddard <stoddard@apache.org>2001-02-14 22:05:36 +0100
committerBill Stoddard <stoddard@apache.org>2001-02-14 22:05:36 +0100
commitf5129aa30a31517b66dac3706430903c7b04a895 (patch)
treedcc43866324375b5394e5cff4391075f63e4d8bd
parent Sorry, cleaning up the naughty bits that should not have been committed. (diff)
downloadapache2-f5129aa30a31517b66dac3706430903c7b04a895.tar.xz
apache2-f5129aa30a31517b66dac3706430903c7b04a895.zip
Fix lingering close (and make it more efficient). We were blocking on
apr_read() for 30 seconds for each lingering close. What we want to do is block for 2 seconds. If we do not read any bytes from the client in that time, close the connection. If we do read bytes, then wait 2 more seconds to see if more arrive, etc. Repeat for MAX_SECS_TO_LINGER if needed. This should clear the way to get 2.0 running on apache.org! git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88167 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--server/connection.c26
1 files changed, 12 insertions, 14 deletions
diff --git a/server/connection.c b/server/connection.c
index 6b69711822..703c600c3f 100644
--- a/server/connection.c
+++ b/server/connection.c
@@ -148,14 +148,14 @@ AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c)
* TCP RST packets to be sent which can tear down a connection before
* all the response data has been sent to the client.
*/
-
+#define SECONDS_TO_LINGER 2
void ap_lingering_close(conn_rec *c)
{
char dummybuf[512];
- apr_time_t start;
- apr_size_t nbytes;
+ apr_size_t nbytes = sizeof(dummybuf);
apr_status_t rc;
- int timeout;
+ apr_int32_t timeout;
+ apr_int32_t total_linger_time = 0;
#ifdef NO_LINGCLOSE
ap_flush_conn(c); /* just close it */
@@ -187,23 +187,21 @@ void ap_lingering_close(conn_rec *c)
}
/* Read all data from the peer until we reach "end-of-file" (FIN
- * from peer) or we've exceeded our overall timeout.
+ * 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.
*/
-
- start = apr_time_now();
- timeout = MAX_SECS_TO_LINGER * APR_USEC_PER_SEC;
+ timeout = SECONDS_TO_LINGER * APR_USEC_PER_SEC;
for (;;) {
apr_setsocketopt(c->client_socket, APR_SO_TIMEOUT, timeout);
nbytes = sizeof(dummybuf);
rc = apr_recv(c->client_socket, dummybuf, &nbytes);
if (rc != APR_SUCCESS || nbytes == 0) break;
- /* how much time has elapsed? */
- timeout = (int)((apr_time_now() - start) / APR_USEC_PER_SEC);
- if (timeout >= MAX_SECS_TO_LINGER) break;
-
- /* figure out the new timeout */
- timeout = (int)((MAX_SECS_TO_LINGER - timeout) * APR_USEC_PER_SEC);
+ total_linger_time += SECONDS_TO_LINGER;
+ if (total_linger_time >= MAX_SECS_TO_LINGER) {
+ break;
+ }
}
apr_socket_close(c->client_socket);