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

(-)server/mpm/worker/worker.c (-1 / +107 lines)
Lines 233-244 Link Here
233
 */
233
 */
234
#define WORKER_SIGNAL       AP_SIG_GRACEFUL
234
#define WORKER_SIGNAL       AP_SIG_GRACEFUL
235
235
236
#ifdef HAVE_PTHREAD_KILL
237
/* An array of thread and socket descriptors in use by each thread used to
238
 * perform a non-graceful (forced) shutdown of the server. */
239
static volatile sig_atomic_t suspend_workers = 0;
240
static struct worker_data {
241
    apr_os_thread_t       *thread;
242
    apr_socket_t          *socket;
243
    volatile sig_atomic_t suspended;
244
} *worker_data;
245
#else
236
/* An array of socket descriptors in use by each thread used to
246
/* An array of socket descriptors in use by each thread used to
237
 * perform a non-graceful (forced) shutdown of the server. */
247
 * perform a non-graceful (forced) shutdown of the server. */
238
static apr_socket_t **worker_sockets;
248
static apr_socket_t **worker_sockets;
249
#endif
239
250
251
#ifdef HAVE_PTHREAD_KILL
252
static void worker_signal_handler(int sig)
253
{
254
    int i;
255
256
    /* find our thread */
257
    for (i = 0; i < threads_per_child; i++) {
258
        if (worker_data[i].thread &&
259
            pthread_equal(*worker_data[i].thread, pthread_self())) {
260
            break;
261
        }
262
    }
263
264
    /* just in case we overshot */
265
    if (i >= threads_per_child) {
266
        return;
267
    }
268
269
    /* suspend and then wait to resume */
270
    if (suspend_workers) {
271
        worker_data[i].suspended = 1;
272
273
        while (suspend_workers) {
274
            apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL / 5);
275
        }
276
    }
277
278
    worker_data[i].suspended = 0;
279
}
280
240
static void close_worker_sockets(void)
281
static void close_worker_sockets(void)
241
{
282
{
283
    int i, j, csd;
284
285
    suspend_workers = 1;
286
287
    /* interrupt worker threads */
288
    for (i = 0; i < threads_per_child; i++) {
289
        if (worker_data[i].thread) {
290
            /* try sending the signal twice */
291
            if (pthread_kill(*worker_data[i].thread, WORKER_SIGNAL) == -1) {
292
                pthread_kill(*worker_data[i].thread, WORKER_SIGNAL);
293
            }
294
        }
295
    }
296
297
    /* wait for threads to suspend, but press ahead after a while anyway */
298
    for (j = 0; j < 25; j++) {
299
        int sum = 0;
300
301
        apr_sleep(SCOREBOARD_MAINTENANCE_INTERVAL / 5);
302
303
        for (i = 0; i < threads_per_child; i++) {
304
            sum += worker_data[i].suspended;
305
        }
306
307
        if (sum == threads_per_child) {
308
            break;
309
        }
310
    }
311
312
    /* shut down all client sockets */
313
    for (i = 0; i < threads_per_child; i++) {
314
        if (worker_data[i].socket) {
315
            apr_os_sock_get(&csd, worker_data[i].socket);
316
            if (csd != -1) {
317
                shutdown(csd, SHUT_RDWR);
318
            }
319
        }
320
    }
321
322
    suspend_workers = 0;
323
}
324
#else
325
static void close_worker_sockets(void)
326
{
242
    int i;
327
    int i;
243
    for (i = 0; i < threads_per_child; i++) {
328
    for (i = 0; i < threads_per_child; i++) {
244
        if (worker_sockets[i]) {
329
        if (worker_sockets[i]) {
Lines 247-252 Link Here
247
        }
332
        }
248
    }
333
    }
249
}
334
}
335
#endif
250
336
251
static void wakeup_listener(void)
337
static void wakeup_listener(void)
252
{
338
{
Lines 862-868 Link Here
862
948
863
#ifdef HAVE_PTHREAD_KILL
949
#ifdef HAVE_PTHREAD_KILL
864
    unblock_signal(WORKER_SIGNAL);
950
    unblock_signal(WORKER_SIGNAL);
865
    apr_signal(WORKER_SIGNAL, dummy_signal_handler);
951
    apr_signal(WORKER_SIGNAL, worker_signal_handler);
866
#endif
952
#endif
867
953
868
    while (!workers_may_exit) {
954
    while (!workers_may_exit) {
Lines 915-924 Link Here
915
            continue;
1001
            continue;
916
        }
1002
        }
917
        is_idle = 0;
1003
        is_idle = 0;
1004
1005
#ifdef HAVE_PTHREAD_KILL
1006
        worker_data[thread_slot].socket = csd;
1007
#else
918
        worker_sockets[thread_slot] = csd;
1008
        worker_sockets[thread_slot] = csd;
1009
#endif
1010
919
        bucket_alloc = apr_bucket_alloc_create(ptrans);
1011
        bucket_alloc = apr_bucket_alloc_create(ptrans);
920
        process_socket(thd, ptrans, csd, process_slot, thread_slot, bucket_alloc);
1012
        process_socket(thd, ptrans, csd, process_slot, thread_slot, bucket_alloc);
1013
1014
#ifdef HAVE_PTHREAD_KILL
1015
        worker_data[thread_slot].socket = NULL;
1016
#else
921
        worker_sockets[thread_slot] = NULL;
1017
        worker_sockets[thread_slot] = NULL;
1018
#endif
1019
922
        requests_this_child--; 
1020
        requests_this_child--; 
923
        apr_pool_clear(ptrans);
1021
        apr_pool_clear(ptrans);
924
        last_ptrans = ptrans;
1022
        last_ptrans = ptrans;
Lines 1001-1008 Link Here
1001
        clean_child_exit(APEXIT_CHILDFATAL);
1099
        clean_child_exit(APEXIT_CHILDFATAL);
1002
    }
1100
    }
1003
1101
1102
#ifdef HAVE_PTHREAD_KILL
1103
    worker_data = apr_pcalloc(pchild, threads_per_child
1104
                                      * sizeof(*worker_data));
1105
#else
1004
    worker_sockets = apr_pcalloc(pchild, threads_per_child
1106
    worker_sockets = apr_pcalloc(pchild, threads_per_child
1005
                                        * sizeof(apr_socket_t *));
1107
                                        * sizeof(apr_socket_t *));
1108
#endif
1006
1109
1007
    loops = prev_threads_created = 0;
1110
    loops = prev_threads_created = 0;
1008
    while (1) {
1111
    while (1) {
Lines 1038-1043 Link Here
1038
                /* let the parent decide how bad this really is */
1141
                /* let the parent decide how bad this really is */
1039
                clean_child_exit(APEXIT_CHILDSICK);
1142
                clean_child_exit(APEXIT_CHILDSICK);
1040
            }
1143
            }
1144
#ifdef HAVE_PTHREAD_KILL
1145
            apr_os_thread_get(&worker_data[i].thread, threads[i]);
1146
#endif
1041
            threads_created++;
1147
            threads_created++;
1042
        }
1148
        }
1043
        /* Start the listener only when there are workers available */
1149
        /* Start the listener only when there are workers available */

Return to bug 48094