mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
mod_proxy: fix proxy connection cleanup from an n+2 pool.
When connection_destructor() is called after pchild is gone, we can't dereference worker->cp anymore. This happens is debug/one_process mode only, if we exit by calling apr_terminate() or clearing the process pool directly. Fix this by NULL-ing worker->cp in conn_pool_cleanup(), and by registering it as a pre_cleanup. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1822531 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -1306,10 +1306,7 @@ static void socket_cleanup(proxy_conn_rec *conn)
|
|||||||
|
|
||||||
static apr_status_t conn_pool_cleanup(void *theworker)
|
static apr_status_t conn_pool_cleanup(void *theworker)
|
||||||
{
|
{
|
||||||
proxy_worker *worker = (proxy_worker *)theworker;
|
((proxy_worker *)theworker)->cp = NULL;
|
||||||
if (worker->cp->res) {
|
|
||||||
worker->cp->pool = NULL;
|
|
||||||
}
|
|
||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1347,14 +1344,6 @@ static apr_status_t connection_cleanup(void *theconn)
|
|||||||
proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
|
proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
|
||||||
proxy_worker *worker = conn->worker;
|
proxy_worker *worker = conn->worker;
|
||||||
|
|
||||||
/*
|
|
||||||
* If the connection pool is NULL the worker
|
|
||||||
* cleanup has been run. Just return.
|
|
||||||
*/
|
|
||||||
if (!worker->cp->pool) {
|
|
||||||
return APR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn->r) {
|
if (conn->r) {
|
||||||
apr_pool_destroy(conn->r->pool);
|
apr_pool_destroy(conn->r->pool);
|
||||||
conn->r = NULL;
|
conn->r = NULL;
|
||||||
@@ -1476,7 +1465,7 @@ static apr_status_t connection_destructor(void *resource, void *params,
|
|||||||
proxy_worker *worker = params;
|
proxy_worker *worker = params;
|
||||||
|
|
||||||
/* Destroy the pool only if not called from reslist_destroy */
|
/* Destroy the pool only if not called from reslist_destroy */
|
||||||
if (worker->cp->pool) {
|
if (worker->cp) {
|
||||||
proxy_conn_rec *conn = resource;
|
proxy_conn_rec *conn = resource;
|
||||||
apr_pool_destroy(conn->pool);
|
apr_pool_destroy(conn->pool);
|
||||||
}
|
}
|
||||||
@@ -1907,9 +1896,8 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser
|
|||||||
connection_constructor, connection_destructor,
|
connection_constructor, connection_destructor,
|
||||||
worker, worker->cp->pool);
|
worker, worker->cp->pool);
|
||||||
|
|
||||||
apr_pool_cleanup_register(worker->cp->pool, (void *)worker,
|
apr_pool_pre_cleanup_register(worker->cp->pool, worker,
|
||||||
conn_pool_cleanup,
|
conn_pool_cleanup);
|
||||||
apr_pool_cleanup_null);
|
|
||||||
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00930)
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00930)
|
||||||
"initialized pool in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d",
|
"initialized pool in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d",
|
||||||
|
Reference in New Issue
Block a user