diff options
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++; |