From edb2fa4611f230b187189859bf97aa8c0f4d651c Mon Sep 17 00:00:00 2001 From: Bill Stoddard Date: Thu, 6 Jul 2000 15:13:30 +0000 Subject: [PATCH] WinNT: Implement acceptex socket reuse. Make sure that the ap_sendfile flags argument is properly initialized for all platforms. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85775 13f79535-47bb-0310-9956-ffa450edef68 --- modules/cache/mod_file_cache.c | 12 ++++++++++-- modules/http/http_protocol.c | 11 ++++++++++- server/mpm/winnt/mpm_winnt.c | 18 +++++++++++++++--- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/modules/cache/mod_file_cache.c b/modules/cache/mod_file_cache.c index 4bd0385dd8..634b3bcde9 100644 --- a/modules/cache/mod_file_cache.c +++ b/modules/cache/mod_file_cache.c @@ -421,6 +421,14 @@ static int sendfile_handler(request_rec *r, a_file *file, int rangestatus) struct iovec iov; ap_hdtr_t hdtr; ap_hdtr_t *phdtr = &hdtr; + ap_int32_t flags = 0; + + if (!r->connection->keepalive) { + /* Prepare the socket to be reused. Ignored on systems + * that do not support reusing the accept socket + */ + flags |= APR_SENDFILE_DISCONNECT_SOCKET; + } /* * We want to send any data held in the client buffer on the @@ -446,7 +454,7 @@ static int sendfile_handler(request_rec *r, a_file *file, int rangestatus) phdtr, &offset, &length, - 0); + flags); } else { while (ap_each_byterange(r, &offset, &length)) { @@ -455,7 +463,7 @@ static int sendfile_handler(request_rec *r, a_file *file, int rangestatus) phdtr, &offset, &length, - 0); + flags); phdtr = NULL; } } diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index ea4bcdf9e1..1563afb225 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -2250,6 +2250,7 @@ API_EXPORT(long) ap_send_fd(ap_file_t *fd, request_rec *r) { ap_size_t len = r->finfo.size; #if APR_HAS_SENDFILE + ap_int32_t flags = 0; if (!r->chunked) { ap_status_t rv; ap_bsetopt(r->connection->client, BO_TIMEOUT, @@ -2257,12 +2258,20 @@ API_EXPORT(long) ap_send_fd(ap_file_t *fd, request_rec *r) ? &r->server->keep_alive_timeout : &r->server->timeout); ap_bflush(r->connection->client); + + if (!r->connection->keepalive) { + /* Prepare the socket to be reused. Ignored on systems + * that do not support reusing the accept socket + */ + flags |= APR_SENDFILE_DISCONNECT_SOCKET; + } + rv = iol_sendfile(r->connection->client->iol, fd, /* The file to send */ NULL, /* header and trailer iovecs */ 0, /* Offset in file to begin sending from */ &len, - 0); + flags); if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "ap_send_fd: iol_sendfile failed."); diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index a587e40010..3fe15f3bbe 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -944,7 +944,6 @@ static ap_inline ap_status_t reset_acceptex_context(PCOMP_CONTEXT context) "reset_acceptex_context: AcceptEx failed for " "listening socket: %d and accept socket: %d", nsd, context->accept_socket); - context->accept_socket = INVALID_SOCKET; return lasterror; } } @@ -1071,6 +1070,7 @@ static void worker_main(int child_num) while (1) { conn_rec *current_conn; ap_iol *iol; + ap_int32_t disconnected; /* Grab a connection off the network */ if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { @@ -1099,8 +1099,20 @@ static void worker_main(int child_num) child_num); ap_process_connection(current_conn); - ap_lingering_close(current_conn); - context->accept_socket = INVALID_SOCKET; + + + ap_getsocketopt(context->sock, APR_SO_DISCONNECTED, &disconnected); + if (disconnected) { + /* Kill the clean-up registered by the iol. We want to leave + * the accept socket open because we are about to try to + * reuse it + */ + ap_bpop_iol(&iol, context->conn_io); + } + else { + context->accept_socket = INVALID_SOCKET; + ap_lingering_close(current_conn); + } } ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, server_conf, -- 2.40.0