From: Stefan Eissing Date: Thu, 16 Mar 2017 08:40:52 +0000 (+0000) Subject: On the trunk: X-Git-Tag: 2.5.0-alpha~554 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=804c19c4f781604920123dd364a2ae8f6c7b3cba;p=apache On the trunk: mod_http2: fixed PR60869 by making h2 workers exit explicitly waking up all threads to exit in a defined way. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1787141 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index bd768316e3..e54947a5b5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_http2: fixed PR60869 by making h2 workers exit explicitly waking up + all threads to exit in a defined way. [Stefan Eissing] + *) Add and directives. [Joe Orton] *) mod_syslog: Support use of optional "tag" in syslog entries. diff --git a/modules/http2/h2_workers.c b/modules/http2/h2_workers.c index 1dcfb2fcd7..cbaf1bcb36 100644 --- a/modules/http2/h2_workers.c +++ b/modules/http2/h2_workers.c @@ -235,6 +235,28 @@ static apr_status_t h2_workers_start(h2_workers *workers) return status; } +static apr_status_t workers_pool_cleanup(void *data) +{ + h2_workers *workers = data; + h2_worker *w; + + if (!workers->aborted) { + workers->aborted = 1; + + /* before we go, cleanup any zombies and abort the rest */ + cleanup_zombies(workers, 1); + w = H2_WORKER_LIST_FIRST(&workers->workers); + while (w != H2_WORKER_LIST_SENTINEL(&workers->workers)) { + h2_worker_abort(w); + w = H2_WORKER_NEXT(w); + } + apr_thread_mutex_lock(workers->lock); + apr_thread_cond_broadcast(workers->mplx_added); + apr_thread_mutex_unlock(workers->lock); + } + return APR_SUCCESS; +} + h2_workers *h2_workers_create(server_rec *s, apr_pool_t *server_pool, int min_workers, int max_workers, apr_size_t max_tx_handles) @@ -283,50 +305,20 @@ h2_workers *h2_workers_create(server_rec *s, apr_pool_t *server_pool, if (status == APR_SUCCESS) { status = apr_thread_cond_create(&workers->mplx_added, workers->pool); } - if (status == APR_SUCCESS) { status = apr_thread_mutex_create(&workers->tx_lock, APR_THREAD_MUTEX_DEFAULT, workers->pool); } - if (status == APR_SUCCESS) { status = h2_workers_start(workers); } - - if (status != APR_SUCCESS) { - h2_workers_destroy(workers); - workers = NULL; + if (status == APR_SUCCESS) { + apr_pool_pre_cleanup_register(pool, workers, workers_pool_cleanup); + return workers; } } - return workers; -} - -void h2_workers_destroy(h2_workers *workers) -{ - /* before we go, cleanup any zombie workers that may have accumulated */ - cleanup_zombies(workers, 1); - - if (workers->mplx_added) { - apr_thread_cond_destroy(workers->mplx_added); - workers->mplx_added = NULL; - } - if (workers->lock) { - apr_thread_mutex_destroy(workers->lock); - workers->lock = NULL; - } - while (!H2_MPLX_LIST_EMPTY(&workers->mplxs)) { - h2_mplx *m = H2_MPLX_LIST_FIRST(&workers->mplxs); - H2_MPLX_REMOVE(m); - } - while (!H2_WORKER_LIST_EMPTY(&workers->workers)) { - h2_worker *w = H2_WORKER_LIST_FIRST(&workers->workers); - H2_WORKER_REMOVE(w); - } - if (workers->pool) { - apr_pool_destroy(workers->pool); - /* workers is gone */ - } + return NULL; } apr_status_t h2_workers_register(h2_workers *workers, struct h2_mplx *m) diff --git a/modules/http2/h2_workers.h b/modules/http2/h2_workers.h index ae7b4d8969..b96cff3613 100644 --- a/modules/http2/h2_workers.h +++ b/modules/http2/h2_workers.h @@ -67,10 +67,6 @@ h2_workers *h2_workers_create(server_rec *s, apr_pool_t *pool, int min_size, int max_size, apr_size_t max_tx_handles); -/* Destroy the worker pool and all its threads. - */ -void h2_workers_destroy(h2_workers *workers); - /** * Registers a h2_mplx for task scheduling. If this h2_mplx runs * out of tasks, it will be automatically be unregistered. Should