1 --- httpd-2.2.14-v/server/mpm/worker/worker.c 2007-07-18 00:48:25.000000000 +1000
2 +++ httpd-2.2.14/server/mpm/worker/worker.c 2009-11-02 09:40:23.129750043 +1100
5 #define APR_WANT_STRFUNC
7 +#include "apr_atomic.h"
13 #define WORKER_SIGNAL AP_SIG_GRACEFUL
15 +#ifdef HAVE_PTHREAD_KILL
16 +/* Variables for suspending the worker threads. */
17 +static volatile sig_atomic_t suspend_workers = 0;
18 +static apr_uint32_t suspended_workers;
19 +static apr_os_thread_t **worker_os_threads;
22 /* An array of socket descriptors in use by each thread used to
23 * perform a non-graceful (forced) shutdown of the server. */
24 static apr_socket_t **worker_sockets;
26 +#ifdef HAVE_PTHREAD_KILL
27 +static void worker_signal_handler(int sig)
29 + /* wait here if we are being suspended, otherwise just exit */
30 + if (suspend_workers) {
33 + apr_atomic_inc32(&suspended_workers);
35 + sigfillset(&sigset);
36 + sigdelset(&sigset, WORKER_SIGNAL);
37 + sigsuspend(&sigset);
41 +static void close_worker_sockets(void)
45 + suspend_workers = 1;
46 + apr_atomic_set32(&suspended_workers, 0);
48 + /* suspend worker threads */
49 + for (i = 0; i < ap_threads_per_child; i++) {
50 + if (worker_os_threads[i]) {
51 + pthread_kill(*worker_os_threads[i], WORKER_SIGNAL);
55 + /* wait for threads to suspend, but press ahead after a while anyway */
57 + apr_atomic_read32(&suspended_workers) < ap_threads_per_child && i < 25;
59 + apr_sleep(apr_time_from_sec(1) / 5);
62 + /* shut down all client sockets */
63 + for (i = 0; i < ap_threads_per_child; i++) {
64 + if (worker_sockets[i]) {
65 + apr_os_sock_get(&csd, worker_sockets[i]);
67 + shutdown(csd, SHUT_RDWR);
72 + suspend_workers = 0;
74 + /* resume worker threads */
75 + for (i = 0; i < ap_threads_per_child; i++) {
76 + if (worker_os_threads[i]) {
77 + pthread_kill(*worker_os_threads[i], WORKER_SIGNAL);
82 static void close_worker_sockets(void)
91 static void wakeup_listener(void)
95 #ifdef HAVE_PTHREAD_KILL
96 unblock_signal(WORKER_SIGNAL);
97 - apr_signal(WORKER_SIGNAL, dummy_signal_handler);
98 + apr_signal(WORKER_SIGNAL, worker_signal_handler);
101 while (!workers_may_exit) {
102 @@ -977,6 +1042,10 @@
104 worker_sockets = apr_pcalloc(pchild, ap_threads_per_child
105 * sizeof(apr_socket_t *));
106 +#ifdef HAVE_PTHREAD_KILL
107 + worker_os_threads = apr_pcalloc(pchild, ap_threads_per_child
108 + * sizeof(*worker_os_threads));
111 loops = prev_threads_created = 0;
113 @@ -1012,6 +1081,9 @@
114 /* let the parent decide how bad this really is */
115 clean_child_exit(APEXIT_CHILDSICK);
117 +#ifdef HAVE_PTHREAD_KILL
118 + apr_os_thread_get(&worker_os_threads[i], threads[i]);
122 /* Start the listener only when there are workers available */