Skip to content

Commit b3e19c3

Browse files
committed
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
1 parent 1d948e9 commit b3e19c3

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

changes-entries/start-threads.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*) worker, event: Avoid possible hangs and crashes during shutdown of
2+
child processes that fail to start their configured threads.
3+
[Yann Ylavic, Eric Covener]

server/mpm/event/event.c

+19-2
Original file line numberDiff line numberDiff line change
@@ -2745,11 +2745,28 @@ static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy)
27452745
rv = ap_thread_create(&threads[i], thread_attr,
27462746
worker_thread, my_info, pruntime);
27472747
if (rv != APR_SUCCESS) {
2748+
ap_update_child_status_from_indexes(my_child_num, i, SERVER_DEAD, NULL);
27482749
ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
27492750
APLOGNO(03104)
27502751
"ap_thread_create: unable to create worker thread");
2751-
/* let the parent decide how bad this really is */
2752-
signal_threads(listener_started ? ST_GRACEFUL : ST_UNGRACEFUL);
2752+
/* Let the parent decide how bad this really is by returning
2753+
* APEXIT_CHILDSICK. If threads were created already let them
2754+
* stop cleanly first to avoid deadlocks in clean_child_exit(),
2755+
* just stop creating new ones here (but set resource_shortage
2756+
* to return APEXIT_CHILDSICK still when the child exists).
2757+
*/
2758+
if (threads_created) {
2759+
resource_shortage = 1;
2760+
signal_threads(ST_GRACEFUL);
2761+
if (!listener_started) {
2762+
workers_may_exit = 1;
2763+
ap_queue_term(worker_queue);
2764+
/* wake up main POD thread too */
2765+
kill(ap_my_pid, SIGTERM);
2766+
}
2767+
apr_thread_exit(thd, APR_SUCCESS);
2768+
return NULL;
2769+
}
27532770
clean_child_exit(APEXIT_CHILDSICK);
27542771
}
27552772
threads_created++;

server/mpm/worker/worker.c

+19-1
Original file line numberDiff line numberDiff line change
@@ -979,9 +979,27 @@ static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy)
979979
rv = ap_thread_create(&threads[i], thread_attr,
980980
worker_thread, my_info, pruntime);
981981
if (rv != APR_SUCCESS) {
982+
ap_update_child_status_from_indexes(my_child_num, i, SERVER_DEAD, NULL);
982983
ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(03142)
983984
"ap_thread_create: unable to create worker thread");
984-
/* let the parent decide how bad this really is */
985+
/* Let the parent decide how bad this really is by returning
986+
* APEXIT_CHILDSICK. If threads were created already let them
987+
* stop cleanly first to avoid deadlocks in clean_child_exit(),
988+
* just stop creating new ones here (but set resource_shortage
989+
* to return APEXIT_CHILDSICK still when the child exists).
990+
*/
991+
if (threads_created) {
992+
resource_shortage = 1;
993+
signal_threads(ST_GRACEFUL);
994+
if (!listener_started) {
995+
workers_may_exit = 1;
996+
ap_queue_term(worker_queue);
997+
/* wake up main POD thread too */
998+
kill(ap_my_pid, SIGTERM);
999+
}
1000+
apr_thread_exit(thd, APR_SUCCESS);
1001+
return NULL;
1002+
}
9851003
clean_child_exit(APEXIT_CHILDSICK);
9861004
}
9871005
threads_created++;

0 commit comments

Comments
 (0)