summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2015-03-09 23:11:45 +0000
committerYann Ylavic <ylavic@apache.org>2015-03-09 23:11:45 +0000
commitd6bcf7e4f25f83761fd2673a044d814baab078dd (patch)
tree57d683951f1657813689223105adbc6290668429 /server
parent627711af7f1183897a063e3306d3be60db5bd0a2 (diff)
downloadhttpd-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
Diffstat (limited to 'server')
-rw-r--r--server/mpm/motorz/motorz.c62
-rw-r--r--server/mpm/motorz/motorz.h6
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;