diff options
author | Eric Covener <covener@apache.org> | 2024-03-13 02:26:54 +0100 |
---|---|---|
committer | Eric Covener <covener@apache.org> | 2024-03-13 02:26:54 +0100 |
commit | b3e19c3cebdf07aec9ffef07dc4a81a666450e33 (patch) | |
tree | 76e0d6fd6e5eedf4f0f40d29f2161e2e6306e4e0 /server | |
parent | use graceful exit if lister started (diff) | |
download | apache2-b3e19c3cebdf07aec9ffef07dc4a81a666450e33.tar.xz apache2-b3e19c3cebdf07aec9ffef07dc4a81a666450e33.zip |
shutdown carefully when threads don't start
Submitted By: ylavic, covener
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1916267 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server')
-rw-r--r-- | server/mpm/event/event.c | 21 | ||||
-rw-r--r-- | server/mpm/worker/worker.c | 20 |
2 files changed, 38 insertions, 3 deletions
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index 831d3c2516..3841142c60 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -2745,11 +2745,28 @@ static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy) rv = ap_thread_create(&threads[i], thread_attr, worker_thread, my_info, pruntime); if (rv != APR_SUCCESS) { + ap_update_child_status_from_indexes(my_child_num, i, SERVER_DEAD, NULL); ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03104) "ap_thread_create: unable to create worker thread"); - /* let the parent decide how bad this really is */ - signal_threads(listener_started ? ST_GRACEFUL : ST_UNGRACEFUL); + /* Let the parent decide how bad this really is by returning + * APEXIT_CHILDSICK. If threads were created already let them + * stop cleanly first to avoid deadlocks in clean_child_exit(), + * just stop creating new ones here (but set resource_shortage + * to return APEXIT_CHILDSICK still when the child exists). + */ + if (threads_created) { + resource_shortage = 1; + signal_threads(ST_GRACEFUL); + if (!listener_started) { + workers_may_exit = 1; + ap_queue_term(worker_queue); + /* wake up main POD thread too */ + kill(ap_my_pid, SIGTERM); + } + apr_thread_exit(thd, APR_SUCCESS); + return NULL; + } clean_child_exit(APEXIT_CHILDSICK); } threads_created++; diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index aebbd0b6f4..ecf38aedfc 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -979,9 +979,27 @@ static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) rv = ap_thread_create(&threads[i], thread_attr, worker_thread, my_info, pruntime); if (rv != APR_SUCCESS) { + ap_update_child_status_from_indexes(my_child_num, i, SERVER_DEAD, NULL); ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03142) "ap_thread_create: unable to create worker thread"); - /* let the parent decide how bad this really is */ + /* Let the parent decide how bad this really is by returning + * APEXIT_CHILDSICK. If threads were created already let them + * stop cleanly first to avoid deadlocks in clean_child_exit(), + * just stop creating new ones here (but set resource_shortage + * to return APEXIT_CHILDSICK still when the child exists). + */ + if (threads_created) { + resource_shortage = 1; + signal_threads(ST_GRACEFUL); + if (!listener_started) { + workers_may_exit = 1; + ap_queue_term(worker_queue); + /* wake up main POD thread too */ + kill(ap_my_pid, SIGTERM); + } + apr_thread_exit(thd, APR_SUCCESS); + return NULL; + } clean_child_exit(APEXIT_CHILDSICK); } threads_created++; |