1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

Follow up to r1879449: yet better MPM poll callback API.

Let pass a const pfds to the MPM, for it to make a copy on the given pool
as needed.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879451 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yann Ylavic
2020-07-02 15:49:53 +00:00
parent ec2c547006
commit c9472d3fc9
7 changed files with 41 additions and 65 deletions

View File

@@ -650,7 +650,6 @@
* mpm_unregister_poll_callback hook. * mpm_unregister_poll_callback hook.
* 20200702.0 (2.5.1-dev) Add pool arg to mpm_register_poll_callback and * 20200702.0 (2.5.1-dev) Add pool arg to mpm_register_poll_callback and
* mpm_register_poll_callback_timeout hooks * mpm_register_poll_callback_timeout hooks
*
*/ */
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */ #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */

View File

@@ -224,7 +224,7 @@ AP_DECLARE(apr_status_t) ap_mpm_register_timed_callback(
*/ */
AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback( AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback(
apr_pool_t *p, apr_array_header_t *pfds, apr_pool_t *p, const apr_array_header_t *pfds,
ap_mpm_callback_fn_t *cbfn, void *baton); ap_mpm_callback_fn_t *cbfn, void *baton);
/** /**
@@ -247,7 +247,7 @@ AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback(
*/ */
AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback_timeout( AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback_timeout(
apr_pool_t *p, apr_array_header_t *pfds, apr_pool_t *p, const apr_array_header_t *pfds,
ap_mpm_callback_fn_t *cbfn, ap_mpm_callback_fn_t *tofn, ap_mpm_callback_fn_t *cbfn, ap_mpm_callback_fn_t *tofn,
void *baton, apr_time_t timeout); void *baton, apr_time_t timeout);

View File

@@ -427,7 +427,7 @@ AP_DECLARE_HOOK(apr_status_t, mpm_register_timed_callback,
* @ingroup hooks * @ingroup hooks
*/ */
AP_DECLARE_HOOK(apr_status_t, mpm_register_poll_callback, AP_DECLARE_HOOK(apr_status_t, mpm_register_poll_callback,
(apr_pool_t *p, apr_array_header_t *pds, (apr_pool_t *p, const apr_array_header_t *pds,
ap_mpm_callback_fn_t *cbfn, void *baton)) ap_mpm_callback_fn_t *cbfn, void *baton))
/* register the specified callback, with timeout /* register the specified callback, with timeout
@@ -435,9 +435,8 @@ AP_DECLARE_HOOK(apr_status_t, mpm_register_poll_callback,
* *
*/ */
AP_DECLARE_HOOK(apr_status_t, mpm_register_poll_callback_timeout, AP_DECLARE_HOOK(apr_status_t, mpm_register_poll_callback_timeout,
(apr_pool_t *p, apr_array_header_t *pds, (apr_pool_t *p, const apr_array_header_t *pds,
ap_mpm_callback_fn_t *cbfn, ap_mpm_callback_fn_t *cbfn, ap_mpm_callback_fn_t *tofn,
ap_mpm_callback_fn_t *tofn,
void *baton, apr_time_t timeout)) void *baton, apr_time_t timeout))
/** Resume the suspended connection /** Resume the suspended connection

View File

@@ -256,7 +256,6 @@ typedef struct {
proxy_tunnel_rec *tunnel; proxy_tunnel_rec *tunnel;
apr_pool_t *async_pool; apr_pool_t *async_pool;
apr_array_header_t *pfds;
apr_interval_time_t idle_timeout; apr_interval_time_t idle_timeout;
unsigned int can_go_async :1, unsigned int can_go_async :1,
@@ -319,26 +318,6 @@ static void proxy_http_async_cb(void *baton)
/* Pump both ends until they'd block and then start over again */ /* Pump both ends until they'd block and then start over again */
status = ap_proxy_tunnel_run(req->tunnel); status = ap_proxy_tunnel_run(req->tunnel);
if (status == HTTP_GATEWAY_TIME_OUT) { if (status == HTTP_GATEWAY_TIME_OUT) {
if (!req->async_pool) {
/* Create the MPM's (req->)pfds off of our tunnel's, and
* the subpool used by the MPM to alloc its own temporary
* data, which we want to clear on the next round (above)
* to avoid leaks.
*/
req->pfds = apr_array_copy(req->p, req->tunnel->pfds);
APR_ARRAY_IDX(req->pfds, 0, apr_pollfd_t).client_data = NULL;
APR_ARRAY_IDX(req->pfds, 1, apr_pollfd_t).client_data = NULL;
apr_pool_create(&req->async_pool, req->p);
}
else {
/* Update only reqevents of the MPM's pfds with our tunnel's,
* the rest didn't change.
*/
APR_ARRAY_IDX(req->pfds, 0, apr_pollfd_t).reqevents =
APR_ARRAY_IDX(req->tunnel->pfds, 0, apr_pollfd_t).reqevents;
APR_ARRAY_IDX(req->pfds, 1, apr_pollfd_t).reqevents =
APR_ARRAY_IDX(req->tunnel->pfds, 1, apr_pollfd_t).reqevents;
}
status = SUSPENDED; status = SUSPENDED;
} }
break; break;
@@ -356,7 +335,16 @@ static void proxy_http_async_cb(void *baton)
"proxy %s: suspended, going async", "proxy %s: suspended, going async",
req->proto); req->proto);
ap_mpm_register_poll_callback_timeout(req->async_pool, req->pfds, if (!req->async_pool) {
/* Create the subpool used by the MPM to alloc its own
* temporary data, which we want to clear on the next
* round (above) to avoid leaks.
*/
apr_pool_create(&req->async_pool, req->p);
}
ap_mpm_register_poll_callback_timeout(req->async_pool,
req->tunnel->pfds,
proxy_http_async_cb, proxy_http_async_cb,
proxy_http_async_cancel_cb, proxy_http_async_cancel_cb,
req, req->idle_timeout); req, req->idle_timeout);

View File

@@ -29,7 +29,6 @@ typedef struct ws_baton_t {
request_rec *r; request_rec *r;
proxy_conn_rec *backend; proxy_conn_rec *backend;
proxy_tunnel_rec *tunnel; proxy_tunnel_rec *tunnel;
apr_array_header_t *pfds;
apr_pool_t *async_pool; apr_pool_t *async_pool;
const char *scheme; const char *scheme;
} ws_baton_t; } ws_baton_t;
@@ -96,15 +95,8 @@ static void proxy_wstunnel_callback(void *b)
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, baton->r, ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, baton->r,
"proxy_wstunnel_callback suspend"); "proxy_wstunnel_callback suspend");
/* Update only reqevents of the MPM's pfds with our tunnel's, ap_mpm_register_poll_callback_timeout(baton->async_pool,
* the rest didn't change. baton->tunnel->pfds,
*/
APR_ARRAY_IDX(baton->pfds, 0, apr_pollfd_t).reqevents =
APR_ARRAY_IDX(baton->tunnel->pfds, 0, apr_pollfd_t).reqevents;
APR_ARRAY_IDX(baton->pfds, 1, apr_pollfd_t).reqevents =
APR_ARRAY_IDX(baton->tunnel->pfds, 1, apr_pollfd_t).reqevents;
ap_mpm_register_poll_callback_timeout(baton->async_pool, baton->pfds,
proxy_wstunnel_callback, proxy_wstunnel_callback,
proxy_wstunnel_cancel_callback, proxy_wstunnel_cancel_callback,
baton, dconf->idle_timeout); baton, dconf->idle_timeout);
@@ -275,18 +267,15 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
tunnel->timeout = dconf->async_delay; tunnel->timeout = dconf->async_delay;
status = proxy_wstunnel_pump(baton, 1); status = proxy_wstunnel_pump(baton, 1);
if (status == SUSPENDED) { if (status == SUSPENDED) {
/* Create the MPM's (baton->)pfds off of our tunnel's, and /* Create the subpool used by the MPM to alloc its own
* the subpool used by the MPM to alloc its own temporary * temporary data, which we want to clear on the next
* data, which we want to clear on the next round (above) * round (above) to avoid leaks.
* to avoid leaks.
*/ */
baton->pfds = apr_array_copy(baton->r->pool, baton->tunnel->pfds);
APR_ARRAY_IDX(baton->pfds, 0, apr_pollfd_t).client_data = NULL;
APR_ARRAY_IDX(baton->pfds, 1, apr_pollfd_t).client_data = NULL;
apr_pool_create(&baton->async_pool, baton->r->pool); apr_pool_create(&baton->async_pool, baton->r->pool);
rv = ap_mpm_register_poll_callback_timeout( rv = ap_mpm_register_poll_callback_timeout(
baton->async_pool, baton->pfds, baton->async_pool,
baton->tunnel->pfds,
proxy_wstunnel_callback, proxy_wstunnel_callback,
proxy_wstunnel_cancel_callback, proxy_wstunnel_cancel_callback,
baton, baton,

View File

@@ -1605,11 +1605,11 @@ static apr_status_t event_cleanup_poll_callback(void *data)
} }
static apr_status_t event_register_poll_callback_ex(apr_pool_t *p, static apr_status_t event_register_poll_callback_ex(apr_pool_t *p,
apr_array_header_t *pfds, const apr_array_header_t *pfds,
ap_mpm_callback_fn_t *cbfn, ap_mpm_callback_fn_t *cbfn,
ap_mpm_callback_fn_t *tofn, ap_mpm_callback_fn_t *tofn,
void *baton, void *baton,
apr_time_t timeout) apr_time_t timeout)
{ {
socket_callback_baton_t *scb = apr_pcalloc(p, sizeof(*scb)); socket_callback_baton_t *scb = apr_pcalloc(p, sizeof(*scb));
listener_poll_type *pt = apr_palloc(p, sizeof(*pt)); listener_poll_type *pt = apr_palloc(p, sizeof(*pt));
@@ -1621,12 +1621,12 @@ static apr_status_t event_register_poll_callback_ex(apr_pool_t *p,
scb->cbfunc = cbfn; scb->cbfunc = cbfn;
scb->user_baton = baton; scb->user_baton = baton;
scb->pfds = pfds; scb->pfds = apr_array_copy(p, pfds);
apr_pool_pre_cleanup_register(p, pfds, event_cleanup_poll_callback); apr_pool_pre_cleanup_register(p, scb->pfds, event_cleanup_poll_callback);
for (i = 0; i < pfds->nelts; i++) { for (i = 0; i < scb->pfds->nelts; i++) {
apr_pollfd_t *pfd = (apr_pollfd_t *)pfds->elts + i; apr_pollfd_t *pfd = (apr_pollfd_t *)scb->pfds->elts + i;
if (pfd->reqevents) { if (pfd->reqevents) {
if (pfd->reqevents & APR_POLLIN) { if (pfd->reqevents & APR_POLLIN) {
pfd->reqevents |= APR_POLLHUP; pfd->reqevents |= APR_POLLHUP;
@@ -1641,10 +1641,10 @@ static apr_status_t event_register_poll_callback_ex(apr_pool_t *p,
if (timeout > 0) { if (timeout > 0) {
/* XXX: This cancel timer event can fire before the pollset is updated */ /* XXX: This cancel timer event can fire before the pollset is updated */
scb->cancel_event = event_get_timer_event(timeout, tofn, baton, 1, pfds); scb->cancel_event = event_get_timer_event(timeout, tofn, baton, 1, scb->pfds);
} }
for (i = 0; i < pfds->nelts; i++) { for (i = 0; i < scb->pfds->nelts; i++) {
apr_pollfd_t *pfd = (apr_pollfd_t *)pfds->elts + i; apr_pollfd_t *pfd = (apr_pollfd_t *)scb->pfds->elts + i;
if (pfd->client_data) { if (pfd->client_data) {
rc = apr_pollset_add(event_pollset, pfd); rc = apr_pollset_add(event_pollset, pfd);
if (rc != APR_SUCCESS) { if (rc != APR_SUCCESS) {
@@ -1656,7 +1656,7 @@ static apr_status_t event_register_poll_callback_ex(apr_pool_t *p,
} }
static apr_status_t event_register_poll_callback(apr_pool_t *p, static apr_status_t event_register_poll_callback(apr_pool_t *p,
apr_array_header_t *pfds, const apr_array_header_t *pfds,
ap_mpm_callback_fn_t *cbfn, ap_mpm_callback_fn_t *cbfn,
void *baton) void *baton)
{ {

View File

@@ -110,11 +110,11 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_resume_suspended,
(conn_rec *c), (conn_rec *c),
(c), APR_ENOTIMPL) (c), APR_ENOTIMPL)
AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_register_poll_callback, AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_register_poll_callback,
(apr_pool_t *p, apr_array_header_t *pds, (apr_pool_t *p, const apr_array_header_t *pds,
ap_mpm_callback_fn_t *cbfn, void *baton), ap_mpm_callback_fn_t *cbfn, void *baton),
(p, pds, cbfn, baton), APR_ENOTIMPL) (p, pds, cbfn, baton), APR_ENOTIMPL)
AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_register_poll_callback_timeout, AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, mpm_register_poll_callback_timeout,
(apr_pool_t *p, apr_array_header_t *pds, (apr_pool_t *p, const apr_array_header_t *pds,
ap_mpm_callback_fn_t *cbfn, ap_mpm_callback_fn_t *cbfn,
ap_mpm_callback_fn_t *tofn, ap_mpm_callback_fn_t *tofn,
void *baton, apr_time_t timeout), void *baton, apr_time_t timeout),
@@ -572,15 +572,16 @@ AP_DECLARE(apr_status_t) ap_mpm_register_timed_callback(apr_time_t t,
} }
AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback( AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback(
apr_pool_t *p, apr_array_header_t *pfds, apr_pool_t *p, const apr_array_header_t *pfds,
ap_mpm_callback_fn_t *cbfn, void *baton) ap_mpm_callback_fn_t *cbfn, void *baton)
{ {
return ap_run_mpm_register_poll_callback(p, pfds, cbfn, baton); return ap_run_mpm_register_poll_callback(p, pfds, cbfn, baton);
} }
AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback_timeout( AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback_timeout(
apr_pool_t *p, apr_array_header_t *pfds, ap_mpm_callback_fn_t *cbfn, apr_pool_t *p, const apr_array_header_t *pfds,
ap_mpm_callback_fn_t *tofn, void *baton, apr_time_t timeout) ap_mpm_callback_fn_t *cbfn, ap_mpm_callback_fn_t *tofn,
void *baton, apr_time_t timeout)
{ {
return ap_run_mpm_register_poll_callback_timeout(p, pfds, cbfn, tofn, return ap_run_mpm_register_poll_callback_timeout(p, pfds, cbfn, tofn,
baton, timeout); baton, timeout);