Lines 32-37
Link Here
|
32 |
#include "apr_poll.h" |
32 |
#include "apr_poll.h" |
33 |
#define APR_WANT_STRFUNC |
33 |
#define APR_WANT_STRFUNC |
34 |
#include "apr_want.h" |
34 |
#include "apr_want.h" |
|
|
35 |
#include "apr_atomic.h" |
35 |
|
36 |
|
36 |
#if APR_HAVE_UNISTD_H |
37 |
#if APR_HAVE_UNISTD_H |
37 |
#include <unistd.h> |
38 |
#include <unistd.h> |
Lines 233-244
Link Here
|
233 |
*/ |
234 |
*/ |
234 |
#define WORKER_SIGNAL AP_SIG_GRACEFUL |
235 |
#define WORKER_SIGNAL AP_SIG_GRACEFUL |
235 |
|
236 |
|
|
|
237 |
#ifdef HAVE_PTHREAD_KILL |
238 |
/* Variables for suspending the worker threads. */ |
239 |
static volatile sig_atomic_t suspend_workers = 0; |
240 |
static apr_uint32_t suspended_workers; |
241 |
static apr_os_thread_t **worker_os_threads; |
242 |
#endif |
243 |
|
236 |
/* An array of socket descriptors in use by each thread used to |
244 |
/* An array of socket descriptors in use by each thread used to |
237 |
* perform a non-graceful (forced) shutdown of the server. */ |
245 |
* perform a non-graceful (forced) shutdown of the server. */ |
238 |
static apr_socket_t **worker_sockets; |
246 |
static apr_socket_t **worker_sockets; |
239 |
|
247 |
|
|
|
248 |
#ifdef HAVE_PTHREAD_KILL |
249 |
static void worker_signal_handler(int sig) |
250 |
{ |
251 |
/* wait here if we are being suspended, otherwise just exit */ |
252 |
if (suspend_workers) { |
253 |
sigset_t sigset; |
254 |
|
255 |
apr_atomic_inc32(&suspended_workers); |
256 |
|
257 |
sigfillset(&sigset); |
258 |
sigdelset(&sigset, WORKER_SIGNAL); |
259 |
sigsuspend(&sigset); |
260 |
} |
261 |
} |
262 |
|
240 |
static void close_worker_sockets(void) |
263 |
static void close_worker_sockets(void) |
241 |
{ |
264 |
{ |
|
|
265 |
int i, csd; |
266 |
|
267 |
suspend_workers = 1; |
268 |
apr_atomic_set32(&suspended_workers, 0); |
269 |
|
270 |
/* suspend worker threads */ |
271 |
for (i = 0; i < threads_per_child; i++) { |
272 |
if (worker_os_threads[i]) { |
273 |
pthread_kill(*worker_os_threads[i], WORKER_SIGNAL); |
274 |
} |
275 |
} |
276 |
|
277 |
/* wait for threads to suspend, but press ahead after a while anyway */ |
278 |
for (i = 0; |
279 |
apr_atomic_read32(&suspended_workers) < threads_per_child && i < 25; |
280 |
i++) { |
281 |
apr_sleep(apr_time_from_sec(1) / 5); |
282 |
} |
283 |
|
284 |
/* shut down all client sockets */ |
285 |
for (i = 0; i < threads_per_child; i++) { |
286 |
if (worker_sockets[i]) { |
287 |
apr_os_sock_get(&csd, worker_sockets[i]); |
288 |
if (csd != -1) { |
289 |
shutdown(csd, SHUT_RDWR); |
290 |
} |
291 |
} |
292 |
} |
293 |
|
294 |
suspend_workers = 0; |
295 |
|
296 |
/* resume worker threads */ |
297 |
for (i = 0; i < threads_per_child; i++) { |
298 |
if (worker_os_threads[i]) { |
299 |
pthread_kill(*worker_os_threads[i], WORKER_SIGNAL); |
300 |
} |
301 |
} |
302 |
} |
303 |
#else |
304 |
static void close_worker_sockets(void) |
305 |
{ |
242 |
int i; |
306 |
int i; |
243 |
for (i = 0; i < threads_per_child; i++) { |
307 |
for (i = 0; i < threads_per_child; i++) { |
244 |
if (worker_sockets[i]) { |
308 |
if (worker_sockets[i]) { |
Lines 247-252
Link Here
|
247 |
} |
311 |
} |
248 |
} |
312 |
} |
249 |
} |
313 |
} |
|
|
314 |
#endif |
250 |
|
315 |
|
251 |
static void wakeup_listener(void) |
316 |
static void wakeup_listener(void) |
252 |
{ |
317 |
{ |
Lines 862-868
Link Here
|
862 |
|
927 |
|
863 |
#ifdef HAVE_PTHREAD_KILL |
928 |
#ifdef HAVE_PTHREAD_KILL |
864 |
unblock_signal(WORKER_SIGNAL); |
929 |
unblock_signal(WORKER_SIGNAL); |
865 |
apr_signal(WORKER_SIGNAL, dummy_signal_handler); |
930 |
apr_signal(WORKER_SIGNAL, worker_signal_handler); |
866 |
#endif |
931 |
#endif |
867 |
|
932 |
|
868 |
while (!workers_may_exit) { |
933 |
while (!workers_may_exit) { |
Lines 1003-1008
Link Here
|
1003 |
|
1068 |
|
1004 |
worker_sockets = apr_pcalloc(pchild, threads_per_child |
1069 |
worker_sockets = apr_pcalloc(pchild, threads_per_child |
1005 |
* sizeof(apr_socket_t *)); |
1070 |
* sizeof(apr_socket_t *)); |
|
|
1071 |
#ifdef HAVE_PTHREAD_KILL |
1072 |
worker_os_threads = apr_pcalloc(pchild, threads_per_child |
1073 |
* sizeof(*worker_os_threads)); |
1074 |
#endif |
1006 |
|
1075 |
|
1007 |
loops = prev_threads_created = 0; |
1076 |
loops = prev_threads_created = 0; |
1008 |
while (1) { |
1077 |
while (1) { |
Lines 1038-1043
Link Here
|
1038 |
/* let the parent decide how bad this really is */ |
1107 |
/* let the parent decide how bad this really is */ |
1039 |
clean_child_exit(APEXIT_CHILDSICK); |
1108 |
clean_child_exit(APEXIT_CHILDSICK); |
1040 |
} |
1109 |
} |
|
|
1110 |
#ifdef HAVE_PTHREAD_KILL |
1111 |
apr_os_thread_get(&worker_os_threads[i], threads[i]); |
1112 |
#endif |
1041 |
threads_created++; |
1113 |
threads_created++; |
1042 |
} |
1114 |
} |
1043 |
/* Start the listener only when there are workers available */ |
1115 |
/* Start the listener only when there are workers available */ |