View | Details | Raw Unified | Return to bug 48094
Collapse All | Expand All

(-)server/mpm/worker/worker.c (-1 / +73 lines)
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 */

Return to bug 48094