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

(-)httpd-2.2.14-v/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 226-235 Link Here
226
 */
227
 */
227
#define WORKER_SIGNAL       AP_SIG_GRACEFUL
228
#define WORKER_SIGNAL       AP_SIG_GRACEFUL
228
229
230
#ifdef HAVE_PTHREAD_KILL
231
/* Variables for suspending the worker threads. */
232
static volatile sig_atomic_t suspend_workers = 0;
233
static apr_uint32_t suspended_workers;
234
static apr_os_thread_t **worker_os_threads;
235
#endif
236
229
/* An array of socket descriptors in use by each thread used to
237
/* An array of socket descriptors in use by each thread used to
230
 * perform a non-graceful (forced) shutdown of the server. */
238
 * perform a non-graceful (forced) shutdown of the server. */
231
static apr_socket_t **worker_sockets;
239
static apr_socket_t **worker_sockets;
232
240
241
#ifdef HAVE_PTHREAD_KILL
242
static void worker_signal_handler(int sig)
243
{
244
    /* wait here if we are being suspended, otherwise just exit */
245
    if (suspend_workers) {
246
        sigset_t sigset;
247
248
        apr_atomic_inc32(&suspended_workers);
249
250
        sigfillset(&sigset);
251
        sigdelset(&sigset, WORKER_SIGNAL);
252
        sigsuspend(&sigset);
253
    }
254
}
255
256
static void close_worker_sockets(void)
257
{
258
    int i, csd;
259
260
    suspend_workers = 1;
261
    apr_atomic_set32(&suspended_workers, 0);
262
263
    /* suspend worker threads */
264
    for (i = 0; i < ap_threads_per_child; i++) {
265
        if (worker_os_threads[i]) {
266
            pthread_kill(*worker_os_threads[i], WORKER_SIGNAL);
267
        }
268
    }
269
270
    /* wait for threads to suspend, but press ahead after a while anyway */
271
    for (i = 0;
272
         apr_atomic_read32(&suspended_workers) < ap_threads_per_child && i < 25;
273
         i++) {
274
        apr_sleep(apr_time_from_sec(1) / 5);
275
    }
276
277
    /* shut down all client sockets */
278
    for (i = 0; i < ap_threads_per_child; i++) {
279
        if (worker_sockets[i]) {
280
            apr_os_sock_get(&csd, worker_sockets[i]);
281
            if (csd != -1) {
282
                shutdown(csd, SHUT_RDWR);
283
            }
284
        }
285
    }
286
287
    suspend_workers = 0;
288
289
    /* resume worker threads */
290
    for (i = 0; i < ap_threads_per_child; i++) {
291
        if (worker_os_threads[i]) {
292
            pthread_kill(*worker_os_threads[i], WORKER_SIGNAL);
293
        }
294
    }
295
}
296
#else
233
static void close_worker_sockets(void)
297
static void close_worker_sockets(void)
234
{
298
{
235
    int i;
299
    int i;
Lines 240-245 Link Here
240
        }
304
        }
241
    }
305
    }
242
}
306
}
307
#endif
243
308
244
static void wakeup_listener(void)
309
static void wakeup_listener(void)
245
{
310
{
Lines 836-842 Link Here
836
901
837
#ifdef HAVE_PTHREAD_KILL
902
#ifdef HAVE_PTHREAD_KILL
838
    unblock_signal(WORKER_SIGNAL);
903
    unblock_signal(WORKER_SIGNAL);
839
    apr_signal(WORKER_SIGNAL, dummy_signal_handler);
904
    apr_signal(WORKER_SIGNAL, worker_signal_handler);
840
#endif
905
#endif
841
906
842
    while (!workers_may_exit) {
907
    while (!workers_may_exit) {
Lines 977-982 Link Here
977
1042
978
    worker_sockets = apr_pcalloc(pchild, ap_threads_per_child
1043
    worker_sockets = apr_pcalloc(pchild, ap_threads_per_child
979
                                        * sizeof(apr_socket_t *));
1044
                                        * sizeof(apr_socket_t *));
1045
#ifdef HAVE_PTHREAD_KILL
1046
    worker_os_threads = apr_pcalloc(pchild, ap_threads_per_child
1047
                                           * sizeof(*worker_os_threads));
1048
#endif
980
1049
981
    loops = prev_threads_created = 0;
1050
    loops = prev_threads_created = 0;
982
    while (1) {
1051
    while (1) {
Lines 1012-1017 Link Here
1012
                /* let the parent decide how bad this really is */
1081
                /* let the parent decide how bad this really is */
1013
                clean_child_exit(APEXIT_CHILDSICK);
1082
                clean_child_exit(APEXIT_CHILDSICK);
1014
            }
1083
            }
1084
#ifdef HAVE_PTHREAD_KILL
1085
            apr_os_thread_get(&worker_os_threads[i], threads[i]);
1086
#endif
1015
            threads_created++;
1087
            threads_created++;
1016
        }
1088
        }
1017
        /* Start the listener only when there are workers available */
1089
        /* Start the listener only when there are workers available */

Return to bug 48094