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

(-)httpd-2.2.14-v/server/mpm/worker/worker.c (-1 / +107 lines)
Lines 226-237 Link Here
226
 */
226
 */
227
#define WORKER_SIGNAL       AP_SIG_GRACEFUL
227
#define WORKER_SIGNAL       AP_SIG_GRACEFUL
228
228
229
#ifdef HAVE_PTHREAD_KILL
230
/* An array of thread and socket descriptors in use by each thread used to
231
 * perform a non-graceful (forced) shutdown of the server. */
232
static volatile sig_atomic_t suspend_workers = 0;
233
static struct worker_data {
234
    apr_os_thread_t       *thread;
235
    apr_socket_t          *socket;
236
    volatile sig_atomic_t suspended;
237
} *worker_data;
238
#else
229
/* An array of socket descriptors in use by each thread used to
239
/* An array of socket descriptors in use by each thread used to
230
 * perform a non-graceful (forced) shutdown of the server. */
240
 * perform a non-graceful (forced) shutdown of the server. */
231
static apr_socket_t **worker_sockets;
241
static apr_socket_t **worker_sockets;
242
#endif
243
244
#ifdef HAVE_PTHREAD_KILL
245
static void worker_signal_handler(int sig)
246
{
247
    int i;
248
249
    /* find our thread */
250
    for (i = 0; i < ap_threads_per_child; i++) {
251
        if (worker_data[i].thread &&
252
            pthread_equal(*worker_data[i].thread, pthread_self())) {
253
            break;
254
        }
255
    }
256
257
    /* just in case we overshot */
258
    if (i >= ap_threads_per_child) {
259
        return;
260
    }
261
262
    /* suspend and then wait to resume */
263
    if (suspend_workers) {
264
        worker_data[i].suspended = 1;
265
266
        while (suspend_workers) {
267
            apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL / 5);
268
        }
269
    }
270
271
    worker_data[i].suspended = 0;
272
}
232
273
233
static void close_worker_sockets(void)
274
static void close_worker_sockets(void)
234
{
275
{
276
    int i, j, csd;
277
278
    suspend_workers = 1;
279
280
    /* interrupt worker threads */
281
    for (i = 0; i < ap_threads_per_child; i++) {
282
        if (worker_data[i].thread) {
283
            /* try sending the signal twice */
284
            if (pthread_kill(*worker_data[i].thread, WORKER_SIGNAL) == -1) {
285
                pthread_kill(*worker_data[i].thread, WORKER_SIGNAL);
286
            }
287
        }
288
    }
289
290
    /* wait for threads to suspend, but press ahead after a while anyway */
291
    for (j = 0; j < 25; j++) {
292
        int sum = 0;
293
294
        apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL / 5);
295
296
        for (i = 0; i < ap_threads_per_child; i++) {
297
            sum += worker_data[i].suspended;
298
        }
299
300
        if (sum == ap_threads_per_child) {
301
            break;
302
        }
303
    }
304
305
    /* shut down all client sockets */
306
    for (i = 0; i < ap_threads_per_child; i++) {
307
        if (worker_data[i].socket) {
308
            apr_os_sock_get(&csd, worker_data[i].socket);
309
            if (csd != -1) {
310
                shutdown(csd, SHUT_RDWR);
311
            }
312
        }
313
    }
314
315
    suspend_workers = 0;
316
}
317
#else
318
static void close_worker_sockets(void)
319
{
235
    int i;
320
    int i;
236
    for (i = 0; i < ap_threads_per_child; i++) {
321
    for (i = 0; i < ap_threads_per_child; i++) {
237
        if (worker_sockets[i]) {
322
        if (worker_sockets[i]) {
Lines 240-245 Link Here
240
        }
325
        }
241
    }
326
    }
242
}
327
}
328
#endif
243
329
244
static void wakeup_listener(void)
330
static void wakeup_listener(void)
245
{
331
{
Lines 836-842 Link Here
836
922
837
#ifdef HAVE_PTHREAD_KILL
923
#ifdef HAVE_PTHREAD_KILL
838
    unblock_signal(WORKER_SIGNAL);
924
    unblock_signal(WORKER_SIGNAL);
839
    apr_signal(WORKER_SIGNAL, dummy_signal_handler);
925
    apr_signal(WORKER_SIGNAL, worker_signal_handler);
840
#endif
926
#endif
841
927
842
    while (!workers_may_exit) {
928
    while (!workers_may_exit) {
Lines 889-898 Link Here
889
            continue;
975
            continue;
890
        }
976
        }
891
        is_idle = 0;
977
        is_idle = 0;
978
979
#ifdef HAVE_PTHREAD_KILL
980
        worker_data[thread_slot].socket = csd;
981
#else
892
        worker_sockets[thread_slot] = csd;
982
        worker_sockets[thread_slot] = csd;
983
#endif
984
893
        bucket_alloc = apr_bucket_alloc_create(ptrans);
985
        bucket_alloc = apr_bucket_alloc_create(ptrans);
894
        process_socket(ptrans, csd, process_slot, thread_slot, bucket_alloc);
986
        process_socket(ptrans, csd, process_slot, thread_slot, bucket_alloc);
987
988
#ifdef HAVE_PTHREAD_KILL
989
        worker_data[thread_slot].socket = NULL;
990
#else
895
        worker_sockets[thread_slot] = NULL;
991
        worker_sockets[thread_slot] = NULL;
992
#endif
993
896
        requests_this_child--; /* FIXME: should be synchronized - aaron */
994
        requests_this_child--; /* FIXME: should be synchronized - aaron */
897
        apr_pool_clear(ptrans);
995
        apr_pool_clear(ptrans);
898
        last_ptrans = ptrans;
996
        last_ptrans = ptrans;
Lines 975-982 Link Here
975
        clean_child_exit(APEXIT_CHILDFATAL);
1073
        clean_child_exit(APEXIT_CHILDFATAL);
976
    }
1074
    }
977
1075
1076
#ifdef HAVE_PTHREAD_KILL
1077
    worker_data = apr_pcalloc(pchild, ap_threads_per_child
1078
                                     * sizeof(*worker_data));
1079
#else
978
    worker_sockets = apr_pcalloc(pchild, ap_threads_per_child
1080
    worker_sockets = apr_pcalloc(pchild, ap_threads_per_child
979
                                        * sizeof(apr_socket_t *));
1081
                                        * sizeof(apr_socket_t *));
1082
#endif
980
1083
981
    loops = prev_threads_created = 0;
1084
    loops = prev_threads_created = 0;
982
    while (1) {
1085
    while (1) {
Lines 1012-1017 Link Here
1012
                /* let the parent decide how bad this really is */
1115
                /* let the parent decide how bad this really is */
1013
                clean_child_exit(APEXIT_CHILDSICK);
1116
                clean_child_exit(APEXIT_CHILDSICK);
1014
            }
1117
            }
1118
#ifdef HAVE_PTHREAD_KILL
1119
            apr_os_thread_get(&worker_data[i].thread, threads[i]);
1120
#endif
1015
            threads_created++;
1121
            threads_created++;
1016
        }
1122
        }
1017
        /* Start the listener only when there are workers available */
1123
        /* Start the listener only when there are workers available */

Return to bug 48094