Skip to content

Commit

Permalink
shutdown carefully when threads don't start
Browse files Browse the repository at this point in the history
Submitted By: ylavic, covener


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1916267 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
covener committed Mar 13, 2024
1 parent 1d948e9 commit b3e19c3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
3 changes: 3 additions & 0 deletions changes-entries/start-threads.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*) worker, event: Avoid possible hangs and crashes during shutdown of
child processes that fail to start their configured threads.
[Yann Ylavic, Eric Covener]
21 changes: 19 additions & 2 deletions server/mpm/event/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
Expand Down
20 changes: 19 additions & 1 deletion server/mpm/worker/worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++;
Expand Down

0 comments on commit b3e19c3

Please sign in to comment.