Lines 94-100
static int ap_daemons_min_free=0;
Link Here
|
94 |
static int ap_daemons_max_free=0; |
94 |
static int ap_daemons_max_free=0; |
95 |
static int ap_daemons_limit=0; /* MaxRequestWorkers */ |
95 |
static int ap_daemons_limit=0; /* MaxRequestWorkers */ |
96 |
static int server_limit = 0; |
96 |
static int server_limit = 0; |
97 |
static int mpm_state = AP_MPMQ_STARTING; |
|
|
98 |
|
97 |
|
99 |
/* data retained by prefork across load/unload of the module |
98 |
/* data retained by prefork across load/unload of the module |
100 |
* allocated on first call to pre-config hook; located on |
99 |
* allocated on first call to pre-config hook; located on |
Lines 101-110
static int server_limit = 0;
Link Here
|
101 |
* subsequent calls to pre-config hook |
100 |
* subsequent calls to pre-config hook |
102 |
*/ |
101 |
*/ |
103 |
typedef struct prefork_retained_data { |
102 |
typedef struct prefork_retained_data { |
|
|
103 |
ap_unixd_mpm_retained_data *mpm; |
104 |
|
104 |
int first_server_limit; |
105 |
int first_server_limit; |
105 |
int module_loads; |
|
|
106 |
ap_generation_t my_generation; |
107 |
int volatile is_graceful; /* set from signal handler */ |
108 |
int maxclients_reported; |
106 |
int maxclients_reported; |
109 |
/* |
107 |
/* |
110 |
* The max child slot ever assigned, preserved across restarts. Necessary |
108 |
* The max child slot ever assigned, preserved across restarts. Necessary |
Lines 131-137
typedef struct prefork_child_bucket {
Link Here
|
131 |
ap_listen_rec *listeners; |
129 |
ap_listen_rec *listeners; |
132 |
apr_proc_mutex_t *mutex; |
130 |
apr_proc_mutex_t *mutex; |
133 |
} prefork_child_bucket; |
131 |
} prefork_child_bucket; |
134 |
static int num_buckets; /* Number of listeners buckets */ |
|
|
135 |
static prefork_child_bucket *all_buckets, /* All listeners buckets */ |
132 |
static prefork_child_bucket *all_buckets, /* All listeners buckets */ |
136 |
*my_bucket; /* Current child bucket */ |
133 |
*my_bucket; /* Current child bucket */ |
137 |
|
134 |
|
Lines 215-221
static void prefork_note_child_started(int slot, p
Link Here
|
215 |
ap_scoreboard_image->parent[slot].pid = pid; |
212 |
ap_scoreboard_image->parent[slot].pid = pid; |
216 |
ap_run_child_status(ap_server_conf, |
213 |
ap_run_child_status(ap_server_conf, |
217 |
ap_scoreboard_image->parent[slot].pid, |
214 |
ap_scoreboard_image->parent[slot].pid, |
218 |
retained->my_generation, slot, MPM_CHILD_STARTED); |
215 |
retained->mpm->my_generation, slot, MPM_CHILD_STARTED); |
219 |
} |
216 |
} |
220 |
|
217 |
|
221 |
/* a clean exit from a child with proper cleanup */ |
218 |
/* a clean exit from a child with proper cleanup */ |
Lines 222-228
static void prefork_note_child_started(int slot, p
Link Here
|
222 |
static void clean_child_exit(int code) __attribute__ ((noreturn)); |
219 |
static void clean_child_exit(int code) __attribute__ ((noreturn)); |
223 |
static void clean_child_exit(int code) |
220 |
static void clean_child_exit(int code) |
224 |
{ |
221 |
{ |
225 |
mpm_state = AP_MPMQ_STOPPING; |
222 |
retained->mpm->mpm_state = AP_MPMQ_STOPPING; |
226 |
|
223 |
|
227 |
apr_signal(SIGHUP, SIG_IGN); |
224 |
apr_signal(SIGHUP, SIG_IGN); |
228 |
apr_signal(SIGTERM, SIG_IGN); |
225 |
apr_signal(SIGTERM, SIG_IGN); |
Lines 246-252
static apr_status_t accept_mutex_on(void)
Link Here
|
246 |
if (rv != APR_SUCCESS) { |
243 |
if (rv != APR_SUCCESS) { |
247 |
const char *msg = "couldn't grab the accept mutex"; |
244 |
const char *msg = "couldn't grab the accept mutex"; |
248 |
|
245 |
|
249 |
if (retained->my_generation != |
246 |
if (retained->mpm->my_generation != |
250 |
ap_scoreboard_image->global->running_generation) { |
247 |
ap_scoreboard_image->global->running_generation) { |
251 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00143) "%s", msg); |
248 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00143) "%s", msg); |
252 |
clean_child_exit(0); |
249 |
clean_child_exit(0); |
Lines 265-271
static apr_status_t accept_mutex_off(void)
Link Here
|
265 |
if (rv != APR_SUCCESS) { |
262 |
if (rv != APR_SUCCESS) { |
266 |
const char *msg = "couldn't release the accept mutex"; |
263 |
const char *msg = "couldn't release the accept mutex"; |
267 |
|
264 |
|
268 |
if (retained->my_generation != |
265 |
if (retained->mpm->my_generation != |
269 |
ap_scoreboard_image->global->running_generation) { |
266 |
ap_scoreboard_image->global->running_generation) { |
270 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00145) "%s", msg); |
267 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00145) "%s", msg); |
271 |
/* don't exit here... we have a connection to |
268 |
/* don't exit here... we have a connection to |
Lines 333-342
static int prefork_query(int query_code, int *resu
Link Here
|
333 |
*result = ap_daemons_limit; |
330 |
*result = ap_daemons_limit; |
334 |
break; |
331 |
break; |
335 |
case AP_MPMQ_MPM_STATE: |
332 |
case AP_MPMQ_MPM_STATE: |
336 |
*result = mpm_state; |
333 |
*result = retained->mpm->mpm_state; |
337 |
break; |
334 |
break; |
338 |
case AP_MPMQ_GENERATION: |
335 |
case AP_MPMQ_GENERATION: |
339 |
*result = retained->my_generation; |
336 |
*result = retained->mpm->my_generation; |
340 |
break; |
337 |
break; |
341 |
default: |
338 |
default: |
342 |
*rv = APR_ENOTIMPL; |
339 |
*rv = APR_ENOTIMPL; |
Lines 359-372
static void just_die(int sig)
Link Here
|
359 |
clean_child_exit(0); |
356 |
clean_child_exit(0); |
360 |
} |
357 |
} |
361 |
|
358 |
|
362 |
/* volatile because they're updated from a signal handler */ |
359 |
/* volatile because it's updated from a signal handler */ |
363 |
static int volatile shutdown_pending; |
|
|
364 |
static int volatile restart_pending; |
365 |
static int volatile die_now = 0; |
360 |
static int volatile die_now = 0; |
366 |
|
361 |
|
367 |
static void stop_listening(int sig) |
362 |
static void stop_listening(int sig) |
368 |
{ |
363 |
{ |
369 |
mpm_state = AP_MPMQ_STOPPING; |
364 |
retained->mpm->mpm_state = AP_MPMQ_STOPPING; |
370 |
ap_close_listeners_ex(my_bucket->listeners); |
365 |
ap_close_listeners_ex(my_bucket->listeners); |
371 |
|
366 |
|
372 |
/* For a graceful stop, we want the child to exit when done */ |
367 |
/* For a graceful stop, we want the child to exit when done */ |
Lines 373-488
static void stop_listening(int sig)
Link Here
|
373 |
die_now = 1; |
368 |
die_now = 1; |
374 |
} |
369 |
} |
375 |
|
370 |
|
376 |
static void sig_term(int sig) |
|
|
377 |
{ |
378 |
if (shutdown_pending == 1) { |
379 |
/* Um, is this _probably_ not an error, if the user has |
380 |
* tried to do a shutdown twice quickly, so we won't |
381 |
* worry about reporting it. |
382 |
*/ |
383 |
return; |
384 |
} |
385 |
mpm_state = AP_MPMQ_STOPPING; |
386 |
shutdown_pending = 1; |
387 |
retained->is_graceful = (sig == AP_SIG_GRACEFUL_STOP); |
388 |
} |
389 |
|
390 |
/* restart() is the signal handler for SIGHUP and AP_SIG_GRACEFUL |
391 |
* in the parent process, unless running in ONE_PROCESS mode |
392 |
*/ |
393 |
static void restart(int sig) |
394 |
{ |
395 |
if (restart_pending == 1) { |
396 |
/* Probably not an error - don't bother reporting it */ |
397 |
return; |
398 |
} |
399 |
mpm_state = AP_MPMQ_STOPPING; |
400 |
restart_pending = 1; |
401 |
retained->is_graceful = (sig == AP_SIG_GRACEFUL); |
402 |
} |
403 |
|
404 |
static void set_signals(void) |
405 |
{ |
406 |
#ifndef NO_USE_SIGACTION |
407 |
struct sigaction sa; |
408 |
#endif |
409 |
|
410 |
if (!one_process) { |
411 |
ap_fatal_signal_setup(ap_server_conf, pconf); |
412 |
} |
413 |
|
414 |
#ifndef NO_USE_SIGACTION |
415 |
sigemptyset(&sa.sa_mask); |
416 |
sa.sa_flags = 0; |
417 |
|
418 |
sa.sa_handler = sig_term; |
419 |
if (sigaction(SIGTERM, &sa, NULL) < 0) |
420 |
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00147) "sigaction(SIGTERM)"); |
421 |
#ifdef AP_SIG_GRACEFUL_STOP |
422 |
if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0) |
423 |
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00148) |
424 |
"sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")"); |
425 |
#endif |
426 |
#ifdef SIGINT |
427 |
if (sigaction(SIGINT, &sa, NULL) < 0) |
428 |
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00149) "sigaction(SIGINT)"); |
429 |
#endif |
430 |
#ifdef SIGXCPU |
431 |
sa.sa_handler = SIG_DFL; |
432 |
if (sigaction(SIGXCPU, &sa, NULL) < 0) |
433 |
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00150) "sigaction(SIGXCPU)"); |
434 |
#endif |
435 |
#ifdef SIGXFSZ |
436 |
/* For systems following the LFS standard, ignoring SIGXFSZ allows |
437 |
* a write() beyond the 2GB limit to fail gracefully with E2BIG |
438 |
* rather than terminate the process. */ |
439 |
sa.sa_handler = SIG_IGN; |
440 |
if (sigaction(SIGXFSZ, &sa, NULL) < 0) |
441 |
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00151) "sigaction(SIGXFSZ)"); |
442 |
#endif |
443 |
#ifdef SIGPIPE |
444 |
sa.sa_handler = SIG_IGN; |
445 |
if (sigaction(SIGPIPE, &sa, NULL) < 0) |
446 |
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00152) "sigaction(SIGPIPE)"); |
447 |
#endif |
448 |
|
449 |
/* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy |
450 |
* processing one |
451 |
*/ |
452 |
sigaddset(&sa.sa_mask, SIGHUP); |
453 |
sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); |
454 |
sa.sa_handler = restart; |
455 |
if (sigaction(SIGHUP, &sa, NULL) < 0) |
456 |
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00153) "sigaction(SIGHUP)"); |
457 |
if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) |
458 |
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00154) "sigaction(" AP_SIG_GRACEFUL_STRING ")"); |
459 |
#else |
460 |
if (!one_process) { |
461 |
#ifdef SIGXCPU |
462 |
apr_signal(SIGXCPU, SIG_DFL); |
463 |
#endif /* SIGXCPU */ |
464 |
#ifdef SIGXFSZ |
465 |
apr_signal(SIGXFSZ, SIG_IGN); |
466 |
#endif /* SIGXFSZ */ |
467 |
} |
468 |
|
469 |
apr_signal(SIGTERM, sig_term); |
470 |
#ifdef SIGHUP |
471 |
apr_signal(SIGHUP, restart); |
472 |
#endif /* SIGHUP */ |
473 |
#ifdef AP_SIG_GRACEFUL |
474 |
apr_signal(AP_SIG_GRACEFUL, restart); |
475 |
#endif /* AP_SIG_GRACEFUL */ |
476 |
#ifdef AP_SIG_GRACEFUL_STOP |
477 |
apr_signal(AP_SIG_GRACEFUL_STOP, sig_term); |
478 |
#endif /* AP_SIG_GRACEFUL */ |
479 |
#ifdef SIGPIPE |
480 |
apr_signal(SIGPIPE, SIG_IGN); |
481 |
#endif /* SIGPIPE */ |
482 |
|
483 |
#endif |
484 |
} |
485 |
|
486 |
/***************************************************************** |
371 |
/***************************************************************** |
487 |
* Child process main loop. |
372 |
* Child process main loop. |
488 |
* The following vars are static to avoid getting clobbered by longjmp(); |
373 |
* The following vars are static to avoid getting clobbered by longjmp(); |
Lines 509-517
static void child_main(int child_num_arg, int chil
Link Here
|
509 |
int last_poll_idx = 0; |
394 |
int last_poll_idx = 0; |
510 |
const char *lockfile; |
395 |
const char *lockfile; |
511 |
|
396 |
|
512 |
mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this |
397 |
/* for benefit of any hooks that run as this child initializes */ |
513 |
* child initializes |
398 |
retained->mpm->mpm_state = AP_MPMQ_STARTING; |
514 |
*/ |
|
|
515 |
|
399 |
|
516 |
my_child_num = child_num_arg; |
400 |
my_child_num = child_num_arg; |
517 |
ap_my_pid = getpid(); |
401 |
ap_my_pid = getpid(); |
Lines 537-543
static void child_main(int child_num_arg, int chil
Link Here
|
537 |
apr_pool_tag(ptrans, "transaction"); |
421 |
apr_pool_tag(ptrans, "transaction"); |
538 |
|
422 |
|
539 |
/* close unused listeners and pods */ |
423 |
/* close unused listeners and pods */ |
540 |
for (i = 0; i < num_buckets; i++) { |
424 |
for (i = 0; i < retained->mpm->num_buckets; i++) { |
541 |
if (i != child_bucket) { |
425 |
if (i != child_bucket) { |
542 |
ap_close_listeners_ex(all_buckets[i].listeners); |
426 |
ap_close_listeners_ex(all_buckets[i].listeners); |
543 |
ap_mpm_pod_close(all_buckets[i].pod); |
427 |
ap_mpm_pod_close(all_buckets[i].pod); |
Lines 603-609
static void child_main(int child_num_arg, int chil
Link Here
|
603 |
lr->accept_func = ap_unixd_accept; |
487 |
lr->accept_func = ap_unixd_accept; |
604 |
} |
488 |
} |
605 |
|
489 |
|
606 |
mpm_state = AP_MPMQ_RUNNING; |
490 |
retained->mpm->mpm_state = AP_MPMQ_RUNNING; |
607 |
|
491 |
|
608 |
bucket_alloc = apr_bucket_alloc_create(pchild); |
492 |
bucket_alloc = apr_bucket_alloc_create(pchild); |
609 |
|
493 |
|
Lines 610-616
static void child_main(int child_num_arg, int chil
Link Here
|
610 |
/* die_now is set when AP_SIG_GRACEFUL is received in the child; |
494 |
/* die_now is set when AP_SIG_GRACEFUL is received in the child; |
611 |
* shutdown_pending is set when SIGTERM is received when running |
495 |
* shutdown_pending is set when SIGTERM is received when running |
612 |
* in single process mode. */ |
496 |
* in single process mode. */ |
613 |
while (!die_now && !shutdown_pending) { |
497 |
while (!die_now && !retained->mpm->shutdown_pending) { |
614 |
conn_rec *current_conn; |
498 |
conn_rec *current_conn; |
615 |
void *csd; |
499 |
void *csd; |
616 |
|
500 |
|
Lines 648-654
static void child_main(int child_num_arg, int chil
Link Here
|
648 |
* poll if already signalled |
532 |
* poll if already signalled |
649 |
*/ |
533 |
*/ |
650 |
if (die_now /* in graceful stop/restart */ |
534 |
if (die_now /* in graceful stop/restart */ |
651 |
|| (one_process && shutdown_pending)) { |
535 |
|| (one_process && retained->mpm->shutdown_pending)) { |
652 |
SAFE_ACCEPT(accept_mutex_off()); |
536 |
SAFE_ACCEPT(accept_mutex_off()); |
653 |
clean_child_exit(0); |
537 |
clean_child_exit(0); |
654 |
} |
538 |
} |
Lines 737-743
static void child_main(int child_num_arg, int chil
Link Here
|
737 |
if (ap_mpm_pod_check(my_bucket->pod) == APR_SUCCESS) { /* selected as idle? */ |
621 |
if (ap_mpm_pod_check(my_bucket->pod) == APR_SUCCESS) { /* selected as idle? */ |
738 |
die_now = 1; |
622 |
die_now = 1; |
739 |
} |
623 |
} |
740 |
else if (retained->my_generation != |
624 |
else if (retained->mpm->my_generation != |
741 |
ap_scoreboard_image->global->running_generation) { /* restart? */ |
625 |
ap_scoreboard_image->global->running_generation) { /* restart? */ |
742 |
/* yeah, this could be non-graceful restart, in which case the |
626 |
/* yeah, this could be non-graceful restart, in which case the |
743 |
* parent will kill us soon enough, but why bother checking? |
627 |
* parent will kill us soon enough, but why bother checking? |
Lines 761-773
static int make_child(server_rec *s, int slot, int
Link Here
|
761 |
if (one_process) { |
645 |
if (one_process) { |
762 |
my_bucket = &all_buckets[0]; |
646 |
my_bucket = &all_buckets[0]; |
763 |
|
647 |
|
764 |
apr_signal(SIGHUP, sig_term); |
|
|
765 |
/* Don't catch AP_SIG_GRACEFUL in ONE_PROCESS mode :) */ |
766 |
apr_signal(SIGINT, sig_term); |
767 |
#ifdef SIGQUIT |
768 |
apr_signal(SIGQUIT, SIG_DFL); |
769 |
#endif |
770 |
apr_signal(SIGTERM, sig_term); |
771 |
prefork_note_child_started(slot, getpid()); |
648 |
prefork_note_child_started(slot, getpid()); |
772 |
child_main(slot, 0); |
649 |
child_main(slot, 0); |
773 |
/* NOTREACHED */ |
650 |
/* NOTREACHED */ |
Lines 852-858
static void startup_children(int number_to_start)
Link Here
|
852 |
if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { |
729 |
if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { |
853 |
continue; |
730 |
continue; |
854 |
} |
731 |
} |
855 |
if (make_child(ap_server_conf, i, i % num_buckets) < 0) { |
732 |
if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) { |
856 |
break; |
733 |
break; |
857 |
} |
734 |
} |
858 |
--number_to_start; |
735 |
--number_to_start; |
Lines 913-919
static void perform_idle_server_maintenance(apr_po
Link Here
|
913 |
* shut down gracefully, in case it happened to pick up a request |
790 |
* shut down gracefully, in case it happened to pick up a request |
914 |
* while we were counting |
791 |
* while we were counting |
915 |
*/ |
792 |
*/ |
916 |
bucket_kill_child_record = (bucket_kill_child_record + 1) % num_buckets; |
793 |
bucket_kill_child_record = (bucket_kill_child_record + 1) % retained->mpm->num_buckets; |
917 |
ap_mpm_pod_signal(all_buckets[bucket_kill_child_record].pod); |
794 |
ap_mpm_pod_signal(all_buckets[bucket_kill_child_record].pod); |
918 |
retained->idle_spawn_rate = 1; |
795 |
retained->idle_spawn_rate = 1; |
919 |
} |
796 |
} |
Lines 940-946
static void perform_idle_server_maintenance(apr_po
Link Here
|
940 |
} |
817 |
} |
941 |
for (i = 0; i < free_length; ++i) { |
818 |
for (i = 0; i < free_length; ++i) { |
942 |
bucket_make_child_record++; |
819 |
bucket_make_child_record++; |
943 |
bucket_make_child_record %= num_buckets; |
820 |
bucket_make_child_record %= retained->mpm->num_buckets; |
944 |
make_child(ap_server_conf, free_slots[i], |
821 |
make_child(ap_server_conf, free_slots[i], |
945 |
bucket_make_child_record); |
822 |
bucket_make_child_record); |
946 |
} |
823 |
} |
Lines 972-990
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
972 |
|
849 |
|
973 |
ap_log_pid(pconf, ap_pid_fname); |
850 |
ap_log_pid(pconf, ap_pid_fname); |
974 |
|
851 |
|
975 |
if (!retained->is_graceful) { |
852 |
if (!retained->mpm->was_graceful) { |
976 |
if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { |
853 |
if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { |
977 |
mpm_state = AP_MPMQ_STOPPING; |
854 |
retained->mpm->mpm_state = AP_MPMQ_STOPPING; |
978 |
return !OK; |
855 |
return !OK; |
979 |
} |
856 |
} |
980 |
/* fix the generation number in the global score; we just got a new, |
857 |
/* fix the generation number in the global score; we just got a new, |
981 |
* cleared scoreboard |
858 |
* cleared scoreboard |
982 |
*/ |
859 |
*/ |
983 |
ap_scoreboard_image->global->running_generation = retained->my_generation; |
860 |
ap_scoreboard_image->global->running_generation = retained->mpm->my_generation; |
984 |
} |
861 |
} |
985 |
|
862 |
|
986 |
restart_pending = shutdown_pending = 0; |
863 |
ap_unixd_mpm_set_signals(pconf, one_process); |
987 |
set_signals(); |
|
|
988 |
|
864 |
|
989 |
if (one_process) { |
865 |
if (one_process) { |
990 |
AP_MONCONTROL(1); |
866 |
AP_MONCONTROL(1); |
Lines 997-1010
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
997 |
/* Don't thrash since num_buckets depends on the |
873 |
/* Don't thrash since num_buckets depends on the |
998 |
* system and the number of online CPU cores... |
874 |
* system and the number of online CPU cores... |
999 |
*/ |
875 |
*/ |
1000 |
if (ap_daemons_limit < num_buckets) |
876 |
if (ap_daemons_limit < retained->mpm->num_buckets) |
1001 |
ap_daemons_limit = num_buckets; |
877 |
ap_daemons_limit = retained->mpm->num_buckets; |
1002 |
if (ap_daemons_to_start < num_buckets) |
878 |
if (ap_daemons_to_start < retained->mpm->num_buckets) |
1003 |
ap_daemons_to_start = num_buckets; |
879 |
ap_daemons_to_start = retained->mpm->num_buckets; |
1004 |
if (ap_daemons_min_free < num_buckets) |
880 |
if (ap_daemons_min_free < retained->mpm->num_buckets) |
1005 |
ap_daemons_min_free = num_buckets; |
881 |
ap_daemons_min_free = retained->mpm->num_buckets; |
1006 |
if (ap_daemons_max_free < ap_daemons_min_free + num_buckets) |
882 |
if (ap_daemons_max_free < ap_daemons_min_free + retained->mpm->num_buckets) |
1007 |
ap_daemons_max_free = ap_daemons_min_free + num_buckets; |
883 |
ap_daemons_max_free = ap_daemons_min_free + retained->mpm->num_buckets; |
1008 |
|
884 |
|
1009 |
/* If we're doing a graceful_restart then we're going to see a lot |
885 |
/* If we're doing a graceful_restart then we're going to see a lot |
1010 |
* of children exiting immediately when we get into the main loop |
886 |
* of children exiting immediately when we get into the main loop |
Lines 1018-1024
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
1018 |
if (remaining_children_to_start > ap_daemons_limit) { |
894 |
if (remaining_children_to_start > ap_daemons_limit) { |
1019 |
remaining_children_to_start = ap_daemons_limit; |
895 |
remaining_children_to_start = ap_daemons_limit; |
1020 |
} |
896 |
} |
1021 |
if (!retained->is_graceful) { |
897 |
if (!retained->mpm->was_graceful) { |
1022 |
startup_children(remaining_children_to_start); |
898 |
startup_children(remaining_children_to_start); |
1023 |
remaining_children_to_start = 0; |
899 |
remaining_children_to_start = 0; |
1024 |
} |
900 |
} |
Lines 1043-1051
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
1043 |
: "none", |
919 |
: "none", |
1044 |
apr_proc_mutex_defname()); |
920 |
apr_proc_mutex_defname()); |
1045 |
|
921 |
|
1046 |
mpm_state = AP_MPMQ_RUNNING; |
922 |
retained->mpm->mpm_state = AP_MPMQ_RUNNING; |
1047 |
|
923 |
|
1048 |
while (!restart_pending && !shutdown_pending) { |
924 |
while (!retained->mpm->restart_pending && !retained->mpm->shutdown_pending) { |
1049 |
int child_slot; |
925 |
int child_slot; |
1050 |
apr_exit_why_e exitwhy; |
926 |
apr_exit_why_e exitwhy; |
1051 |
int status, processed_status; |
927 |
int status, processed_status; |
Lines 1069-1076
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
1069 |
*/ |
945 |
*/ |
1070 |
if (child_slot < 0 |
946 |
if (child_slot < 0 |
1071 |
|| ap_get_scoreboard_process(child_slot)->generation |
947 |
|| ap_get_scoreboard_process(child_slot)->generation |
1072 |
== retained->my_generation) { |
948 |
== retained->mpm->my_generation) { |
1073 |
mpm_state = AP_MPMQ_STOPPING; |
949 |
retained->mpm->mpm_state = AP_MPMQ_STOPPING; |
1074 |
return !OK; |
950 |
return !OK; |
1075 |
} |
951 |
} |
1076 |
else { |
952 |
else { |
Lines 1107-1113
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
1107 |
/* handled */ |
983 |
/* handled */ |
1108 |
#endif |
984 |
#endif |
1109 |
} |
985 |
} |
1110 |
else if (retained->is_graceful) { |
986 |
else if (retained->mpm->was_graceful) { |
1111 |
/* Great, we've probably just lost a slot in the |
987 |
/* Great, we've probably just lost a slot in the |
1112 |
* scoreboard. Somehow we don't know about this |
988 |
* scoreboard. Somehow we don't know about this |
1113 |
* child. |
989 |
* child. |
Lines 1140-1148
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
1140 |
perform_idle_server_maintenance(pconf); |
1016 |
perform_idle_server_maintenance(pconf); |
1141 |
} |
1017 |
} |
1142 |
|
1018 |
|
1143 |
mpm_state = AP_MPMQ_STOPPING; |
1019 |
retained->mpm->mpm_state = AP_MPMQ_STOPPING; |
1144 |
|
1020 |
|
1145 |
if (shutdown_pending && !retained->is_graceful) { |
1021 |
if (retained->mpm->shutdown_pending && retained->mpm->is_ungraceful) { |
1146 |
/* Time to shut down: |
1022 |
/* Time to shut down: |
1147 |
* Kill child processes, tell them to call child_exit, etc... |
1023 |
* Kill child processes, tell them to call child_exit, etc... |
1148 |
*/ |
1024 |
*/ |
Lines 1158-1164
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
1158 |
"caught SIGTERM, shutting down"); |
1034 |
"caught SIGTERM, shutting down"); |
1159 |
|
1035 |
|
1160 |
return DONE; |
1036 |
return DONE; |
1161 |
} else if (shutdown_pending) { |
1037 |
} else if (retained->mpm->shutdown_pending) { |
1162 |
/* Time to perform a graceful shut down: |
1038 |
/* Time to perform a graceful shut down: |
1163 |
* Reap the inactive children, and ask the active ones |
1039 |
* Reap the inactive children, and ask the active ones |
1164 |
* to close their listeners, then wait until they are |
1040 |
* to close their listeners, then wait until they are |
Lines 1171-1177
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
1171 |
ap_close_listeners(); |
1047 |
ap_close_listeners(); |
1172 |
|
1048 |
|
1173 |
/* kill off the idle ones */ |
1049 |
/* kill off the idle ones */ |
1174 |
for (i = 0; i < num_buckets; i++) { |
1050 |
for (i = 0; i < retained->mpm->num_buckets; i++) { |
1175 |
ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit); |
1051 |
ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit); |
1176 |
} |
1052 |
} |
1177 |
|
1053 |
|
Lines 1199-1205
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
1199 |
} |
1075 |
} |
1200 |
|
1076 |
|
1201 |
/* Don't really exit until each child has finished */ |
1077 |
/* Don't really exit until each child has finished */ |
1202 |
shutdown_pending = 0; |
1078 |
retained->mpm->shutdown_pending = 0; |
1203 |
do { |
1079 |
do { |
1204 |
/* Pause for a second */ |
1080 |
/* Pause for a second */ |
1205 |
sleep(1); |
1081 |
sleep(1); |
Lines 1215-1221
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
1215 |
break; |
1091 |
break; |
1216 |
} |
1092 |
} |
1217 |
} |
1093 |
} |
1218 |
} while (!shutdown_pending && active_children && |
1094 |
} while (!retained->mpm->shutdown_pending && active_children && |
1219 |
(!ap_graceful_shutdown_timeout || apr_time_now() < cutoff)); |
1095 |
(!ap_graceful_shutdown_timeout || apr_time_now() < cutoff)); |
1220 |
|
1096 |
|
1221 |
/* We might be here because we received SIGTERM, either |
1097 |
/* We might be here because we received SIGTERM, either |
Lines 1239-1253
static int prefork_run(apr_pool_t *_pconf, apr_poo
Link Here
|
1239 |
/* XXX: we really need to make sure this new generation number isn't in |
1115 |
/* XXX: we really need to make sure this new generation number isn't in |
1240 |
* use by any of the children. |
1116 |
* use by any of the children. |
1241 |
*/ |
1117 |
*/ |
1242 |
++retained->my_generation; |
1118 |
++retained->mpm->my_generation; |
1243 |
ap_scoreboard_image->global->running_generation = retained->my_generation; |
1119 |
ap_scoreboard_image->global->running_generation = retained->mpm->my_generation; |
1244 |
|
1120 |
|
1245 |
if (retained->is_graceful) { |
1121 |
if (!retained->mpm->is_ungraceful) { |
1246 |
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00171) |
1122 |
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00171) |
1247 |
"Graceful restart requested, doing restart"); |
1123 |
"Graceful restart requested, doing restart"); |
1248 |
|
1124 |
|
1249 |
/* kill off the idle ones */ |
1125 |
/* kill off the idle ones */ |
1250 |
for (i = 0; i < num_buckets; i++) { |
1126 |
for (i = 0; i < retained->mpm->num_buckets; i++) { |
1251 |
ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit); |
1127 |
ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit); |
1252 |
} |
1128 |
} |
1253 |
|
1129 |
|
Lines 1299-1305
static int prefork_open_logs(apr_pool_t *p, apr_po
Link Here
|
1299 |
pconf = p; |
1175 |
pconf = p; |
1300 |
|
1176 |
|
1301 |
/* the reverse of pre_config, we want this only the first time around */ |
1177 |
/* the reverse of pre_config, we want this only the first time around */ |
1302 |
if (retained->module_loads == 1) { |
1178 |
if (retained->mpm->module_loads == 1) { |
1303 |
startup = 1; |
1179 |
startup = 1; |
1304 |
level_flags |= APLOG_STARTUP; |
1180 |
level_flags |= APLOG_STARTUP; |
1305 |
} |
1181 |
} |
Lines 1312-1333
static int prefork_open_logs(apr_pool_t *p, apr_po
Link Here
|
1312 |
} |
1188 |
} |
1313 |
|
1189 |
|
1314 |
if (one_process) { |
1190 |
if (one_process) { |
1315 |
num_buckets = 1; |
1191 |
retained->mpm->num_buckets = 1; |
1316 |
} |
1192 |
} |
1317 |
else if (!retained->is_graceful) { /* Preserve the number of buckets |
1193 |
else if (!retained->mpm->was_graceful) { |
1318 |
on graceful restarts. */ |
1194 |
/* Preserve the number of buckets on graceful restarts. */ |
1319 |
num_buckets = 0; |
1195 |
retained->mpm->num_buckets = 0; |
1320 |
} |
1196 |
} |
1321 |
if ((rv = ap_duplicate_listeners(pconf, ap_server_conf, |
1197 |
if ((rv = ap_duplicate_listeners(pconf, ap_server_conf, |
1322 |
&listen_buckets, &num_buckets))) { |
1198 |
&listen_buckets, &retained->mpm->num_buckets))) { |
1323 |
ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv, |
1199 |
ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv, |
1324 |
(startup ? NULL : s), APLOGNO(03280) |
1200 |
(startup ? NULL : s), APLOGNO(03280) |
1325 |
"could not duplicate listeners"); |
1201 |
"could not duplicate listeners"); |
1326 |
return !OK; |
1202 |
return !OK; |
1327 |
} |
1203 |
} |
1328 |
all_buckets = apr_pcalloc(pconf, num_buckets * |
1204 |
all_buckets = apr_pcalloc(pconf, retained->mpm->num_buckets * |
1329 |
sizeof(prefork_child_bucket)); |
1205 |
sizeof(prefork_child_bucket)); |
1330 |
for (i = 0; i < num_buckets; i++) { |
1206 |
for (i = 0; i < retained->mpm->num_buckets; i++) { |
1331 |
if ((rv = ap_mpm_pod_open(pconf, &all_buckets[i].pod))) { |
1207 |
if ((rv = ap_mpm_pod_open(pconf, &all_buckets[i].pod))) { |
1332 |
ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv, |
1208 |
ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv, |
1333 |
(startup ? NULL : s), APLOGNO(03281) |
1209 |
(startup ? NULL : s), APLOGNO(03281) |
Lines 1356-1363
static int prefork_pre_config(apr_pool_t *p, apr_p
Link Here
|
1356 |
apr_status_t rv; |
1232 |
apr_status_t rv; |
1357 |
const char *userdata_key = "mpm_prefork_module"; |
1233 |
const char *userdata_key = "mpm_prefork_module"; |
1358 |
|
1234 |
|
1359 |
mpm_state = AP_MPMQ_STARTING; |
|
|
1360 |
|
1361 |
debug = ap_exists_config_define("DEBUG"); |
1235 |
debug = ap_exists_config_define("DEBUG"); |
1362 |
|
1236 |
|
1363 |
if (debug) { |
1237 |
if (debug) { |
Lines 1373-1387
static int prefork_pre_config(apr_pool_t *p, apr_p
Link Here
|
1373 |
|
1247 |
|
1374 |
ap_mutex_register(p, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0); |
1248 |
ap_mutex_register(p, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0); |
1375 |
|
1249 |
|
1376 |
/* sigh, want this only the second time around */ |
|
|
1377 |
retained = ap_retained_data_get(userdata_key); |
1250 |
retained = ap_retained_data_get(userdata_key); |
1378 |
if (!retained) { |
1251 |
if (!retained) { |
1379 |
retained = ap_retained_data_create(userdata_key, sizeof(*retained)); |
1252 |
retained = ap_retained_data_create(userdata_key, sizeof(*retained)); |
|
|
1253 |
retained->mpm = ap_unixd_mpm_get_retained_data(); |
1380 |
retained->max_daemons_limit = -1; |
1254 |
retained->max_daemons_limit = -1; |
1381 |
retained->idle_spawn_rate = 1; |
1255 |
retained->idle_spawn_rate = 1; |
1382 |
} |
1256 |
} |
1383 |
++retained->module_loads; |
1257 |
if (retained->mpm->baton != retained) { |
1384 |
if (retained->module_loads == 2) { |
1258 |
retained->mpm->was_graceful = 0; |
|
|
1259 |
retained->mpm->baton = retained; |
1260 |
} |
1261 |
retained->mpm->mpm_state = AP_MPMQ_STARTING; |
1262 |
++retained->mpm->module_loads; |
1263 |
|
1264 |
/* sigh, want this only the second time around */ |
1265 |
if (retained->mpm->module_loads == 2) { |
1385 |
if (!one_process && !foreground) { |
1266 |
if (!one_process && !foreground) { |
1386 |
/* before we detach, setup crash handlers to log to errorlog */ |
1267 |
/* before we detach, setup crash handlers to log to errorlog */ |
1387 |
ap_fatal_signal_setup(ap_server_conf, pconf); |
1268 |
ap_fatal_signal_setup(ap_server_conf, pconf); |
Lines 1414-1420
static int prefork_check_config(apr_pool_t *p, apr
Link Here
|
1414 |
int startup = 0; |
1295 |
int startup = 0; |
1415 |
|
1296 |
|
1416 |
/* the reverse of pre_config, we want this only the first time around */ |
1297 |
/* the reverse of pre_config, we want this only the first time around */ |
1417 |
if (retained->module_loads == 1) { |
1298 |
if (retained->mpm->module_loads == 1) { |
1418 |
startup = 1; |
1299 |
startup = 1; |
1419 |
} |
1300 |
} |
1420 |
|
1301 |
|