a cleanup registered with the connection_pool. I have also turned
ap_lingering_close into a static function, because it is only used
in connection.c. This is the next step to consolidating all of the
socket function calls. ap_lingering_close will only be added if the
core is dealing with a standard socket.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@91832
13f79535-47bb-0310-9956-
ffa450edef68
AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c);
-/**
- * This function is responsible for the following cases:
- * <pre>
- * we now proceed to read from the client until we get EOF, or until
- * MAX_SECS_TO_LINGER has passed. the reasons for doing this are
- * documented in a draft:
- *
- * http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-connection-00.txt
- *
- * in a nutshell -- if we don't make this effort we risk causing
- * TCP RST packets to be sent which can tear down a connection before
- * all the response data has been sent to the client.
- * </pre>
- * @param c The connection we are closing
- */
-void ap_lingering_close(conn_rec *);
#endif
/* Hooks */
* all the response data has been sent to the client.
*/
#define SECONDS_TO_LINGER 2
-void ap_lingering_close(conn_rec *c)
+static apr_status_t ap_lingering_close(void *dummy)
{
char dummybuf[512];
apr_size_t nbytes = sizeof(dummybuf);
apr_status_t rc;
apr_int32_t timeout;
apr_int32_t total_linger_time = 0;
+ conn_rec *c = dummy;
ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_CLOSING, NULL);
if (c->aborted) {
apr_socket_close(c->client_socket);
- return;
+ return APR_SUCCESS;
}
/* Shut down the socket for write, which will send a FIN
if (apr_shutdown(c->client_socket, APR_SHUTDOWN_WRITE) != APR_SUCCESS ||
c->aborted) {
apr_socket_close(c->client_socket);
- return;
+ return APR_SUCCESS;
}
/* Read all data from the peer until we reach "end-of-file" (FIN
}
apr_socket_close(c->client_socket);
+ return APR_SUCCESS;
}
AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c)
conn->id = id;
+ apr_pool_cleanup_register(p, conn, ap_lingering_close, apr_pool_cleanup_null);
+
return conn;
}
if (current_conn) {
ap_process_connection(current_conn);
- ap_lingering_close(current_conn);
}
}
current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id);
if (current_conn) {
ap_process_connection(current_conn);
- ap_lingering_close(current_conn);
}
}
if (current_conn) {
ap_process_connection(current_conn);
- ap_lingering_close(current_conn);
}
apr_pool_destroy(pconn);
current_conn = ap_new_connection(ptrans, ap_server_conf, csd, my_worker_num);
if (current_conn) {
ap_process_connection(current_conn);
- ap_lingering_close(current_conn);
}
}
current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id);
if (current_conn) {
ap_process_connection(current_conn);
- ap_lingering_close(current_conn);
}
}
my_child_num);
if (current_conn) {
ap_process_connection(current_conn);
- ap_lingering_close(current_conn);
}
/* Check the pod after processing a connection so that we'll go away
if (current_conn) {
ap_process_connection(current_conn);
- ap_lingering_close(current_conn);
}
}
current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id);
if (current_conn) {
ap_process_connection(current_conn);
- ap_lingering_close(current_conn);
}
}
apr_getsocketopt(context->sock, APR_SO_DISCONNECTED, &disconnected);
if (!disconnected) {
context->accept_socket = INVALID_SOCKET;
- ap_lingering_close(c);
}
}
else {
current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id);
if (current_conn) {
ap_process_connection(current_conn);
- ap_lingering_close(current_conn);
}
}