diff options
author | Yann Ylavic <ylavic@apache.org> | 2015-03-09 23:11:45 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2015-03-09 23:11:45 +0000 |
commit | d6bcf7e4f25f83761fd2673a044d814baab078dd (patch) | |
tree | 57d683951f1657813689223105adbc6290668429 | |
parent | 627711af7f1183897a063e3306d3be60db5bd0a2 (diff) | |
download | httpd-d6bcf7e4f25f83761fd2673a044d814baab078dd.tar.gz |
motorz:
Fix access to timer's pool from different threads (timer_event_process).
Set current_thread before calling timer callback.
Reuse timers by using spare_timers from motorz core (acquire/release_timer).
Use KeepAliveTimeout for CONN_STATE_CHECK_REQUEST_LINE_READABLE.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1665381 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | server/mpm/motorz/motorz.c | 62 | ||||
-rw-r--r-- | server/mpm/motorz/motorz.h | 6 |
2 files changed, 47 insertions, 21 deletions
diff --git a/server/mpm/motorz/motorz.c b/server/mpm/motorz/motorz.c index 89f8c37a49..7a741c611b 100644 --- a/server/mpm/motorz/motorz.c +++ b/server/mpm/motorz/motorz.c @@ -81,6 +81,25 @@ static int indexing_compk(void *ac, void *b) return ((*t1 < t2) ? -1 : ((*t1 > t2) ? 1 : 0)); } +static motorz_timer_t *motorz_acquire_timer(motorz_core_t *mz) +{ + motorz_timer_t *elem = mz->spare_timers; + if (elem) { + mz->spare_timers = elem->next; + } + else { + elem = apr_palloc(mz->pool, sizeof *elem); + } + memset(elem, 0, sizeof *elem); + return elem; +} + +static void motorz_release_timer(motorz_core_t *mz, motorz_timer_t *elem) +{ + elem->next = mz->spare_timers; + mz->spare_timers = elem;; +} + static apr_status_t motorz_timer_pool_cleanup(void *baton) { motorz_timer_t *elem = (motorz_timer_t *)baton; @@ -88,6 +107,7 @@ static apr_status_t motorz_timer_pool_cleanup(void *baton) apr_thread_mutex_lock(mz->mtx); apr_skiplist_remove(mz->timer_ring, elem, NULL); + motorz_release_timer(mz, elem); apr_thread_mutex_unlock(mz->mtx); return APR_SUCCESS; @@ -197,19 +217,25 @@ static apr_status_t motorz_io_accept(motorz_core_t *mz, motorz_sb_t *sb) return APR_SUCCESS; } -static void motorz_timer_run(motorz_timer_t *ep) +static void *motorz_timer_invoke(apr_thread_t *thread, void *baton) { - apr_pool_cleanup_kill(ep->pool, ep, motorz_timer_pool_cleanup); + motorz_timer_t *ep = (motorz_timer_t *)baton; + motorz_conn_t *scon = (motorz_conn_t *) ep->baton; + scon->c->current_thread = thread; ep->cb(ep->mz, ep->baton); + + return NULL; } -static void *motorz_timer_invoke(apr_thread_t *thread, void *baton) +static apr_status_t motorz_timer_event_process(motorz_core_t *mz, motorz_timer_t *te) { - motorz_timer_t *ep = (motorz_timer_t *)baton; + apr_pool_cleanup_kill(te->pool, te, motorz_timer_pool_cleanup); + motorz_release_timer(mz, te); - motorz_timer_run(ep); - return NULL; + return apr_thread_pool_push(mz->workers, + motorz_timer_invoke, + te, APR_THREAD_TASK_PRIORITY_NORMAL, NULL); } static void *motorz_io_invoke(apr_thread_t * thread, void *baton) @@ -265,7 +291,7 @@ static void motorz_register_timer(motorz_core_t *mz, apr_thread_mutex_lock(mz->mtx); - elem = (motorz_timer_t *) apr_pcalloc(shutdown_pool, sizeof(motorz_timer_t)); + elem = motorz_acquire_timer(mz); elem->expires = t; elem->cb = cb; @@ -394,9 +420,9 @@ static apr_status_t motorz_io_process(motorz_conn_t *scon) motorz_register_timer(scon->mz, motorz_io_timeout_cb, scon, - scon->c->base_server != - NULL ? scon->c->base_server-> - timeout : ap_server_conf->timeout, + scon->c->base_server != NULL + ? scon->c->base_server->keep_alive_timeout + : ap_server_conf->keep_alive_timeout, scon->pool); scon->pfd.reqevents = ( @@ -538,6 +564,7 @@ static void clean_child_exit(int code) exit(code); } +#if 0 /* unused for now */ static apr_status_t accept_mutex_on(void) { motorz_core_t *mz = motorz_core_get(); @@ -580,6 +607,7 @@ static apr_status_t accept_mutex_off(void) } return APR_SUCCESS; } +#endif /* On some architectures it's safe to do unserialized accept()s in the single * Listen case. But it's never safe to do it in the case where there's @@ -985,16 +1013,10 @@ static void child_main(motorz_core_t *mz, int child_num_arg, int child_bucket) apr_thread_mutex_lock(mz->mtx); /* now iterate any timers and push to worker pool */ - while (te) { - if (te->expires < tnow) { - apr_skiplist_pop(mz->timer_ring, NULL); - apr_thread_pool_push(mz->workers, - motorz_timer_invoke, - te, - APR_THREAD_TASK_PRIORITY_NORMAL, NULL); - } else { - break; - } + while (te && te->expires < tnow) { + apr_skiplist_pop(mz->timer_ring, NULL); + motorz_timer_event_process(mz, te); + te = apr_skiplist_peek(mz->timer_ring); } diff --git a/server/mpm/motorz/motorz.h b/server/mpm/motorz/motorz.h index d97ef25149..0e82dc48b4 100644 --- a/server/mpm/motorz/motorz.h +++ b/server/mpm/motorz/motorz.h @@ -109,6 +109,9 @@ /** * typedefs */ +struct motorz_timer_t; +typedef struct motorz_timer_t motorz_timer_t; + /* data retained by prefork across load/unload of the module * allocated on first call to pre-config hook; located on * subsequent calls to pre-config hook @@ -131,6 +134,7 @@ struct motorz_core_t { apr_pollset_t *pollset; apr_skiplist *timer_ring; apr_thread_pool_t *workers; + motorz_timer_t *spare_timers; }; typedef struct motorz_child_bucket motorz_child_bucket; @@ -161,7 +165,6 @@ typedef void (*motorz_io_file_cb) (motorz_core_t *mz, apr_socket_t *sock, int flags, void *baton); -typedef struct motorz_timer_t motorz_timer_t; struct motorz_timer_t { apr_time_t expires; @@ -169,6 +172,7 @@ struct motorz_timer_t void *baton; apr_pool_t *pool; motorz_core_t *mz; + motorz_timer_t *next; }; typedef struct motorz_conn_t motorz_conn_t; |