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 */ |