summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/mpm/event/event.c21
-rw-r--r--server/mpm/worker/worker.c20
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++;