| 213 |
*/ |
*/ |
| 214 |
#define LISTENER_SIGNAL SIGHUP |
#define LISTENER_SIGNAL SIGHUP |
| 215 |
|
|
| 216 |
|
/* The WORKER_SIGNAL signal will be sent from the main thread to the |
| 217 |
|
* worker threads during an ungraceful restart or shutdown. |
| 218 |
|
* This ensures that on systems (i.e., Linux) where closing the worker |
| 219 |
|
* socket doesn't awake the worker thread when it is polling on the socket |
| 220 |
|
* (especially in apr_wait_for_io_or_timeout() when handling |
| 221 |
|
* Keep-Alive connections), close_worker_sockets() and join_workers() |
| 222 |
|
* still function in timely manner and allow ungraceful shutdowns to |
| 223 |
|
* proceed to completion. Otherwise join_workers() doesn't return |
| 224 |
|
* before the main process decides the child process is non-responsive |
| 225 |
|
* and sends a SIGKILL. |
| 226 |
|
*/ |
| 227 |
|
#define WORKER_SIGNAL AP_SIG_GRACEFUL |
| 228 |
|
|
| 229 |
/* An array of socket descriptors in use by each thread used to |
/* An array of socket descriptors in use by each thread used to |
| 230 |
* perform a non-graceful (forced) shutdown of the server. */ |
* perform a non-graceful (forced) shutdown of the server. */ |
| 231 |
static apr_socket_t **worker_sockets; |
static apr_socket_t **worker_sockets; |
| 834 |
ap_scoreboard_image->servers[process_slot][thread_slot].generation = ap_my_generation; |
ap_scoreboard_image->servers[process_slot][thread_slot].generation = ap_my_generation; |
| 835 |
ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); |
ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); |
| 836 |
|
|
| 837 |
|
#ifdef HAVE_PTHREAD_KILL |
| 838 |
|
unblock_signal(WORKER_SIGNAL); |
| 839 |
|
apr_signal(WORKER_SIGNAL, dummy_signal_handler); |
| 840 |
|
#endif |
| 841 |
|
|
| 842 |
while (!workers_may_exit) { |
while (!workers_may_exit) { |
| 843 |
if (!is_idle) { |
if (!is_idle) { |
| 844 |
rv = ap_queue_info_set_idle(worker_queue_info, last_ptrans); |
rv = ap_queue_info_set_idle(worker_queue_info, last_ptrans); |
| 1094 |
|
|
| 1095 |
for (i = 0; i < ap_threads_per_child; i++) { |
for (i = 0; i < ap_threads_per_child; i++) { |
| 1096 |
if (threads[i]) { /* if we ever created this thread */ |
if (threads[i]) { /* if we ever created this thread */ |
| 1097 |
|
#ifdef HAVE_PTHREAD_KILL |
| 1098 |
|
apr_os_thread_t *worker_os_thread; |
| 1099 |
|
|
| 1100 |
|
apr_os_thread_get(&worker_os_thread, threads[i]); |
| 1101 |
|
pthread_kill(*worker_os_thread, WORKER_SIGNAL); |
| 1102 |
|
#endif |
| 1103 |
|
|
| 1104 |
rv = apr_thread_join(&thread_rv, threads[i]); |
rv = apr_thread_join(&thread_rv, threads[i]); |
| 1105 |
if (rv != APR_SUCCESS) { |
if (rv != APR_SUCCESS) { |
| 1106 |
ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, |
ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, |