Lines 48-53
Link Here
|
48 |
#include "ap_mmn.h" |
48 |
#include "ap_mmn.h" |
49 |
#include "apr_poll.h" |
49 |
#include "apr_poll.h" |
50 |
|
50 |
|
|
|
51 |
#include <stdlib.h> |
52 |
|
51 |
#ifdef HAVE_TIME_H |
53 |
#ifdef HAVE_TIME_H |
52 |
#include <time.h> |
54 |
#include <time.h> |
53 |
#endif |
55 |
#endif |
Lines 86-99
Link Here
|
86 |
|
88 |
|
87 |
/* config globals */ |
89 |
/* config globals */ |
88 |
|
90 |
|
89 |
static apr_proc_mutex_t *accept_mutex; |
91 |
static apr_proc_mutex_t **accept_mutex; |
90 |
static int ap_daemons_to_start=0; |
92 |
static int ap_daemons_to_start=0; |
91 |
static int ap_daemons_min_free=0; |
93 |
static int ap_daemons_min_free=0; |
92 |
static int ap_daemons_max_free=0; |
94 |
static int ap_daemons_max_free=0; |
93 |
static int ap_daemons_limit=0; /* MaxRequestWorkers */ |
95 |
static int ap_daemons_limit=0; /* MaxRequestWorkers */ |
94 |
static int server_limit = 0; |
96 |
static int server_limit = 0; |
95 |
static int mpm_state = AP_MPMQ_STARTING; |
97 |
static int mpm_state = AP_MPMQ_STARTING; |
96 |
static ap_pod_t *pod; |
98 |
static ap_pod_t **pod; |
|
|
99 |
static ap_pod_t *child_pod; |
100 |
static apr_proc_mutex_t *child_mutex; |
101 |
ap_listen_rec *child_listen; |
102 |
int *bucket; /* bucket array for the httpd child processes */ |
97 |
|
103 |
|
98 |
/* data retained by prefork across load/unload of the module |
104 |
/* data retained by prefork across load/unload of the module |
99 |
* allocated on first call to pre-config hook; located on |
105 |
* allocated on first call to pre-config hook; located on |
Lines 117-123
Link Here
|
117 |
* doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by |
123 |
* doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by |
118 |
* without the need to spawn. |
124 |
* without the need to spawn. |
119 |
*/ |
125 |
*/ |
120 |
int idle_spawn_rate; |
126 |
int idle_spawn_rate[1025]; |
121 |
#ifndef MAX_SPAWN_RATE |
127 |
#ifndef MAX_SPAWN_RATE |
122 |
#define MAX_SPAWN_RATE (32) |
128 |
#define MAX_SPAWN_RATE (32) |
123 |
#endif |
129 |
#endif |
Lines 222-235
Link Here
|
222 |
prefork_note_child_killed(/* slot */ 0, 0, 0); |
228 |
prefork_note_child_killed(/* slot */ 0, 0, 0); |
223 |
} |
229 |
} |
224 |
|
230 |
|
225 |
ap_mpm_pod_close(pod); |
231 |
ap_mpm_pod_close(child_pod); |
226 |
chdir_for_gprof(); |
232 |
chdir_for_gprof(); |
227 |
exit(code); |
233 |
exit(code); |
228 |
} |
234 |
} |
229 |
|
235 |
|
230 |
static void accept_mutex_on(void) |
236 |
static void accept_mutex_on(void) |
231 |
{ |
237 |
{ |
232 |
apr_status_t rv = apr_proc_mutex_lock(accept_mutex); |
238 |
apr_status_t rv = apr_proc_mutex_lock(child_mutex); |
233 |
if (rv != APR_SUCCESS) { |
239 |
if (rv != APR_SUCCESS) { |
234 |
const char *msg = "couldn't grab the accept mutex"; |
240 |
const char *msg = "couldn't grab the accept mutex"; |
235 |
|
241 |
|
Lines 247-253
Link Here
|
247 |
|
253 |
|
248 |
static void accept_mutex_off(void) |
254 |
static void accept_mutex_off(void) |
249 |
{ |
255 |
{ |
250 |
apr_status_t rv = apr_proc_mutex_unlock(accept_mutex); |
256 |
apr_status_t rv = apr_proc_mutex_unlock(child_mutex); |
251 |
if (rv != APR_SUCCESS) { |
257 |
if (rv != APR_SUCCESS) { |
252 |
const char *msg = "couldn't release the accept mutex"; |
258 |
const char *msg = "couldn't release the accept mutex"; |
253 |
|
259 |
|
Lines 272-282
Link Here
|
272 |
* when it's safe in the single Listen case. |
278 |
* when it's safe in the single Listen case. |
273 |
*/ |
279 |
*/ |
274 |
#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT |
280 |
#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT |
275 |
#define SAFE_ACCEPT(stmt) do {if (ap_listeners->next) {stmt;}} while(0) |
281 |
#define SAFE_ACCEPT(stmt) do {if (child_listen->next) {stmt;}} while(0) |
276 |
#else |
282 |
#else |
277 |
#define SAFE_ACCEPT(stmt) do {stmt;} while(0) |
283 |
#define SAFE_ACCEPT(stmt) do {stmt;} while(0) |
278 |
#endif |
284 |
#endif |
279 |
|
|
|
280 |
static int prefork_query(int query_code, int *result, apr_status_t *rv) |
285 |
static int prefork_query(int query_code, int *result, apr_status_t *rv) |
281 |
{ |
286 |
{ |
282 |
*rv = APR_SUCCESS; |
287 |
*rv = APR_SUCCESS; |
Lines 521-530
Link Here
|
521 |
apr_pool_create(&ptrans, pchild); |
526 |
apr_pool_create(&ptrans, pchild); |
522 |
apr_pool_tag(ptrans, "transaction"); |
527 |
apr_pool_tag(ptrans, "transaction"); |
523 |
|
528 |
|
524 |
/* needs to be done before we switch UIDs so we have permissions */ |
529 |
/* close unused listeners and pods */ |
|
|
530 |
for (i = 0; i < num_buckets; i++) { |
531 |
if (i != bucket[my_child_num]) { |
532 |
lr = mpm_listen[i]; |
533 |
while(lr) { |
534 |
apr_socket_close(lr->sd); |
535 |
lr = lr->next; |
536 |
} |
537 |
mpm_listen[i]->active = 0; |
538 |
ap_mpm_pod_close(pod[i]); |
539 |
} |
540 |
} |
541 |
|
542 |
/* needs to be done before we switch UIDs so we have permissions */ |
525 |
ap_reopen_scoreboard(pchild, NULL, 0); |
543 |
ap_reopen_scoreboard(pchild, NULL, 0); |
526 |
lockfile = apr_proc_mutex_lockfile(accept_mutex); |
544 |
lockfile = apr_proc_mutex_lockfile(child_mutex); |
527 |
status = apr_proc_mutex_child_init(&accept_mutex, |
545 |
status = apr_proc_mutex_child_init(&child_mutex, |
528 |
lockfile, |
546 |
lockfile, |
529 |
pchild); |
547 |
pchild); |
530 |
if (status != APR_SUCCESS) { |
548 |
if (status != APR_SUCCESS) { |
Lines 532-538
Link Here
|
532 |
"Couldn't initialize cross-process lock in child " |
550 |
"Couldn't initialize cross-process lock in child " |
533 |
"(%s) (%s)", |
551 |
"(%s) (%s)", |
534 |
lockfile ? lockfile : "none", |
552 |
lockfile ? lockfile : "none", |
535 |
apr_proc_mutex_name(accept_mutex)); |
553 |
apr_proc_mutex_name(child_mutex)); |
536 |
clean_child_exit(APEXIT_CHILDFATAL); |
554 |
clean_child_exit(APEXIT_CHILDFATAL); |
537 |
} |
555 |
} |
538 |
|
556 |
|
Lines 554-560
Link Here
|
554 |
clean_child_exit(APEXIT_CHILDSICK); /* assume temporary resource issue */ |
572 |
clean_child_exit(APEXIT_CHILDSICK); /* assume temporary resource issue */ |
555 |
} |
573 |
} |
556 |
|
574 |
|
557 |
for (lr = ap_listeners, i = num_listensocks; i--; lr = lr->next) { |
575 |
for (lr = child_listen, i = num_listensocks; i--; lr = lr->next) { |
558 |
apr_pollfd_t pfd = { 0 }; |
576 |
apr_pollfd_t pfd = { 0 }; |
559 |
|
577 |
|
560 |
pfd.desc_type = APR_POLL_SOCKET; |
578 |
pfd.desc_type = APR_POLL_SOCKET; |
Lines 612-618
Link Here
|
612 |
|
630 |
|
613 |
if (num_listensocks == 1) { |
631 |
if (num_listensocks == 1) { |
614 |
/* There is only one listener record, so refer to that one. */ |
632 |
/* There is only one listener record, so refer to that one. */ |
615 |
lr = ap_listeners; |
633 |
lr = child_listen; |
616 |
} |
634 |
} |
617 |
else { |
635 |
else { |
618 |
/* multiple listening sockets - need to poll */ |
636 |
/* multiple listening sockets - need to poll */ |
Lines 710-716
Link Here
|
710 |
* while we were processing the connection or we are the lucky |
728 |
* while we were processing the connection or we are the lucky |
711 |
* idle server process that gets to die. |
729 |
* idle server process that gets to die. |
712 |
*/ |
730 |
*/ |
713 |
if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */ |
731 |
if (ap_mpm_pod_check(child_pod) == APR_SUCCESS) { /* selected as idle? */ |
714 |
die_now = 1; |
732 |
die_now = 1; |
715 |
} |
733 |
} |
716 |
else if (retained->my_generation != |
734 |
else if (retained->my_generation != |
Lines 750-756
Link Here
|
750 |
(void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, |
768 |
(void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, |
751 |
(request_rec *) NULL); |
769 |
(request_rec *) NULL); |
752 |
|
770 |
|
753 |
|
771 |
child_listen = mpm_listen[bucket[slot]]; |
|
|
772 |
child_mutex = accept_mutex[bucket[slot]]; |
773 |
child_pod = pod[bucket[slot]]; |
754 |
#ifdef _OSD_POSIX |
774 |
#ifdef _OSD_POSIX |
755 |
/* BS2000 requires a "special" version of fork() before a setuid() call */ |
775 |
/* BS2000 requires a "special" version of fork() before a setuid() call */ |
756 |
if ((pid = os_fork(ap_unixd_config.user_name)) == -1) { |
776 |
if ((pid = os_fork(ap_unixd_config.user_name)) == -1) { |
Lines 815-834
Link Here
|
815 |
if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { |
835 |
if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { |
816 |
continue; |
836 |
continue; |
817 |
} |
837 |
} |
|
|
838 |
bucket[i] = i % num_buckets; |
818 |
if (make_child(ap_server_conf, i) < 0) { |
839 |
if (make_child(ap_server_conf, i) < 0) { |
819 |
break; |
840 |
break; |
820 |
} |
841 |
} |
821 |
--number_to_start; |
842 |
--number_to_start; |
822 |
} |
843 |
} |
823 |
} |
844 |
} |
824 |
|
845 |
/* |
825 |
static void perform_idle_server_maintenance(apr_pool_t *p) |
846 |
* patch: execute idle server maintenance on each child group. |
|
|
847 |
*/ |
848 |
static void perform_idle_server_maintenance(apr_pool_t *p, int my_bucket) |
826 |
{ |
849 |
{ |
827 |
int i; |
850 |
int i; |
828 |
int idle_count; |
851 |
int idle_count; |
829 |
worker_score *ws; |
852 |
worker_score *ws; |
830 |
int free_length; |
853 |
int free_length; |
831 |
int free_slots[MAX_SPAWN_RATE]; |
854 |
int free_slots[MAX_SPAWN_RATE/num_buckets]; |
832 |
int last_non_dead; |
855 |
int last_non_dead; |
833 |
int total_non_dead; |
856 |
int total_non_dead; |
834 |
|
857 |
|
Lines 842-854
Link Here
|
842 |
for (i = 0; i < ap_daemons_limit; ++i) { |
865 |
for (i = 0; i < ap_daemons_limit; ++i) { |
843 |
int status; |
866 |
int status; |
844 |
|
867 |
|
845 |
if (i >= retained->max_daemons_limit && free_length == retained->idle_spawn_rate) |
868 |
if (i >= retained->max_daemons_limit && free_length == retained->idle_spawn_rate[my_bucket]) |
846 |
break; |
869 |
break; |
847 |
ws = &ap_scoreboard_image->servers[i][0]; |
870 |
ws = &ap_scoreboard_image->servers[i][0]; |
848 |
status = ws->status; |
871 |
status = ws->status; |
849 |
if (status == SERVER_DEAD) { |
872 |
if (status == SERVER_DEAD) { |
850 |
/* try to keep children numbers as low as possible */ |
873 |
/* try to keep children numbers as low as possible */ |
851 |
if (free_length < retained->idle_spawn_rate) { |
874 |
if (free_length < retained->idle_spawn_rate[my_bucket]) { |
852 |
free_slots[free_length] = i; |
875 |
free_slots[free_length] = i; |
853 |
++free_length; |
876 |
++free_length; |
854 |
} |
877 |
} |
Lines 860-866
Link Here
|
860 |
* So we hopefully won't need to fork more if we count it. |
883 |
* So we hopefully won't need to fork more if we count it. |
861 |
* This depends on the ordering of SERVER_READY and SERVER_STARTING. |
884 |
* This depends on the ordering of SERVER_READY and SERVER_STARTING. |
862 |
*/ |
885 |
*/ |
863 |
if (status <= SERVER_READY) { |
886 |
if ((status <= SERVER_READY) && (bucket[i] == my_bucket)) { |
864 |
++ idle_count; |
887 |
++ idle_count; |
865 |
} |
888 |
} |
866 |
|
889 |
|
Lines 869-883
Link Here
|
869 |
} |
892 |
} |
870 |
} |
893 |
} |
871 |
retained->max_daemons_limit = last_non_dead + 1; |
894 |
retained->max_daemons_limit = last_non_dead + 1; |
872 |
if (idle_count > ap_daemons_max_free) { |
895 |
if (idle_count > ap_daemons_max_free/num_buckets) { |
873 |
/* kill off one child... we use the pod because that'll cause it to |
896 |
/* kill off one child... we use the pod because that'll cause it to |
874 |
* shut down gracefully, in case it happened to pick up a request |
897 |
* shut down gracefully, in case it happened to pick up a request |
875 |
* while we were counting |
898 |
* while we were counting |
876 |
*/ |
899 |
*/ |
877 |
ap_mpm_pod_signal(pod); |
900 |
ap_mpm_pod_signal(pod[my_bucket], my_bucket); |
878 |
retained->idle_spawn_rate = 1; |
901 |
retained->idle_spawn_rate[my_bucket] = 1; |
879 |
} |
902 |
} |
880 |
else if (idle_count < ap_daemons_min_free) { |
903 |
else if (idle_count < ap_daemons_min_free/num_buckets) { |
881 |
/* terminate the free list */ |
904 |
/* terminate the free list */ |
882 |
if (free_length == 0) { |
905 |
if (free_length == 0) { |
883 |
/* only report this condition once */ |
906 |
/* only report this condition once */ |
Lines 887-904
Link Here
|
887 |
" raising the MaxRequestWorkers setting"); |
910 |
" raising the MaxRequestWorkers setting"); |
888 |
retained->maxclients_reported = 1; |
911 |
retained->maxclients_reported = 1; |
889 |
} |
912 |
} |
890 |
retained->idle_spawn_rate = 1; |
913 |
retained->idle_spawn_rate[my_bucket] = 1; |
891 |
} |
914 |
} |
892 |
else { |
915 |
else { |
893 |
if (retained->idle_spawn_rate >= 8) { |
916 |
if (retained->idle_spawn_rate[my_bucket] >= 8) { |
894 |
ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00162) |
917 |
ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00162) |
895 |
"server seems busy, (you may need " |
918 |
"server seems busy, (you may need " |
896 |
"to increase StartServers, or Min/MaxSpareServers), " |
919 |
"to increase StartServers, or Min/MaxSpareServers), " |
897 |
"spawning %d children, there are %d idle, and " |
920 |
"spawning %d children, there are %d idle, and " |
898 |
"%d total children", retained->idle_spawn_rate, |
921 |
"%d total children", retained->idle_spawn_rate[my_bucket], |
899 |
idle_count, total_non_dead); |
922 |
idle_count, total_non_dead); |
900 |
} |
923 |
} |
901 |
for (i = 0; i < free_length; ++i) { |
924 |
for (i = 0; i < free_length; ++i) { |
|
|
925 |
bucket[free_slots[i]] = my_bucket; |
902 |
make_child(ap_server_conf, free_slots[i]); |
926 |
make_child(ap_server_conf, free_slots[i]); |
903 |
} |
927 |
} |
904 |
/* the next time around we want to spawn twice as many if this |
928 |
/* the next time around we want to spawn twice as many if this |
Lines 907-919
Link Here
|
907 |
if (retained->hold_off_on_exponential_spawning) { |
931 |
if (retained->hold_off_on_exponential_spawning) { |
908 |
--retained->hold_off_on_exponential_spawning; |
932 |
--retained->hold_off_on_exponential_spawning; |
909 |
} |
933 |
} |
910 |
else if (retained->idle_spawn_rate < MAX_SPAWN_RATE) { |
934 |
else if (retained->idle_spawn_rate[my_bucket] < MAX_SPAWN_RATE/num_buckets) { |
911 |
retained->idle_spawn_rate *= 2; |
935 |
retained->idle_spawn_rate[my_bucket] *= 2; |
912 |
} |
936 |
} |
913 |
} |
937 |
} |
914 |
} |
938 |
} |
915 |
else { |
939 |
else { |
916 |
retained->idle_spawn_rate = 1; |
940 |
retained->idle_spawn_rate[my_bucket] = 1; |
917 |
} |
941 |
} |
918 |
} |
942 |
} |
919 |
|
943 |
|
Lines 926-940
Link Here
|
926 |
int index; |
950 |
int index; |
927 |
int remaining_children_to_start; |
951 |
int remaining_children_to_start; |
928 |
apr_status_t rv; |
952 |
apr_status_t rv; |
|
|
953 |
int i; |
929 |
|
954 |
|
930 |
ap_log_pid(pconf, ap_pid_fname); |
955 |
ap_log_pid(pconf, ap_pid_fname); |
931 |
|
956 |
|
932 |
/* Initialize cross-process accept lock */ |
957 |
bucket = apr_palloc(_pconf, sizeof(int) * ap_daemons_limit); |
933 |
rv = ap_proc_mutex_create(&accept_mutex, NULL, AP_ACCEPT_MUTEX_TYPE, NULL, |
958 |
/* Initialize cross-process accept lock for each bucket*/ |
934 |
s, _pconf, 0); |
959 |
accept_mutex = apr_palloc(_pconf, sizeof(apr_proc_mutex_t *) * num_buckets); |
935 |
if (rv != APR_SUCCESS) { |
960 |
for (i = 0; i < num_buckets; i++) { |
936 |
mpm_state = AP_MPMQ_STOPPING; |
961 |
rv = ap_proc_mutex_create(&accept_mutex[i], NULL, AP_ACCEPT_MUTEX_TYPE, NULL, |
937 |
return DONE; |
962 |
s, _pconf, 0); |
|
|
963 |
if (rv != APR_SUCCESS) { |
964 |
mpm_state = AP_MPMQ_STOPPING; |
965 |
return DONE; |
966 |
} |
938 |
} |
967 |
} |
939 |
|
968 |
|
940 |
if (!retained->is_graceful) { |
969 |
if (!retained->is_graceful) { |
Lines 953-964
Link Here
|
953 |
|
982 |
|
954 |
if (one_process) { |
983 |
if (one_process) { |
955 |
AP_MONCONTROL(1); |
984 |
AP_MONCONTROL(1); |
|
|
985 |
bucket[0] = 0; |
956 |
make_child(ap_server_conf, 0); |
986 |
make_child(ap_server_conf, 0); |
957 |
/* NOTREACHED */ |
987 |
/* NOTREACHED */ |
958 |
} |
988 |
} |
959 |
else { |
989 |
else { |
960 |
if (ap_daemons_max_free < ap_daemons_min_free + 1) /* Don't thrash... */ |
990 |
if (ap_daemons_max_free < ap_daemons_min_free + num_buckets) /* Don't thrash... */ |
961 |
ap_daemons_max_free = ap_daemons_min_free + 1; |
991 |
ap_daemons_max_free = ap_daemons_min_free + num_buckets; |
962 |
|
992 |
|
963 |
/* If we're doing a graceful_restart then we're going to see a lot |
993 |
/* If we're doing a graceful_restart then we're going to see a lot |
964 |
* of children exiting immediately when we get into the main loop |
994 |
* of children exiting immediately when we get into the main loop |
Lines 991-997
Link Here
|
991 |
ap_log_command_line(plog, s); |
1021 |
ap_log_command_line(plog, s); |
992 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00165) |
1022 |
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00165) |
993 |
"Accept mutex: %s (default: %s)", |
1023 |
"Accept mutex: %s (default: %s)", |
994 |
apr_proc_mutex_name(accept_mutex), |
1024 |
apr_proc_mutex_name(accept_mutex[0]), |
995 |
apr_proc_mutex_defname()); |
1025 |
apr_proc_mutex_defname()); |
996 |
|
1026 |
|
997 |
mpm_state = AP_MPMQ_RUNNING; |
1027 |
mpm_state = AP_MPMQ_RUNNING; |
Lines 1041-1047
Link Here
|
1041 |
/* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc) |
1071 |
/* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc) |
1042 |
* cut the fork rate to the minimum |
1072 |
* cut the fork rate to the minimum |
1043 |
*/ |
1073 |
*/ |
1044 |
retained->idle_spawn_rate = 1; |
1074 |
retained->idle_spawn_rate[bucket[child_slot]] = 1; |
1045 |
} |
1075 |
} |
1046 |
else if (remaining_children_to_start |
1076 |
else if (remaining_children_to_start |
1047 |
&& child_slot < ap_daemons_limit) { |
1077 |
&& child_slot < ap_daemons_limit) { |
Lines 1086-1093
Link Here
|
1086 |
*/ |
1116 |
*/ |
1087 |
continue; |
1117 |
continue; |
1088 |
} |
1118 |
} |
1089 |
|
1119 |
for (i = 0; i < num_buckets; i++) { |
1090 |
perform_idle_server_maintenance(pconf); |
1120 |
perform_idle_server_maintenance(pconf, i); |
|
|
1121 |
} |
1091 |
} |
1122 |
} |
1092 |
} /* one_process */ |
1123 |
} /* one_process */ |
1093 |
|
1124 |
|
Lines 1122-1128
Link Here
|
1122 |
ap_close_listeners(); |
1153 |
ap_close_listeners(); |
1123 |
|
1154 |
|
1124 |
/* kill off the idle ones */ |
1155 |
/* kill off the idle ones */ |
1125 |
ap_mpm_pod_killpg(pod, retained->max_daemons_limit); |
1156 |
for (i = 0; i < num_buckets; i++) { |
|
|
1157 |
ap_mpm_pod_killpg(pod[i], i, retained->max_daemons_limit); |
1158 |
} |
1126 |
|
1159 |
|
1127 |
/* Send SIGUSR1 to the active children */ |
1160 |
/* Send SIGUSR1 to the active children */ |
1128 |
active_children = 0; |
1161 |
active_children = 0; |
Lines 1196-1203
Link Here
|
1196 |
"Graceful restart requested, doing restart"); |
1229 |
"Graceful restart requested, doing restart"); |
1197 |
|
1230 |
|
1198 |
/* kill off the idle ones */ |
1231 |
/* kill off the idle ones */ |
1199 |
ap_mpm_pod_killpg(pod, retained->max_daemons_limit); |
1232 |
for (i = 0; i < num_buckets; i++) { |
1200 |
|
1233 |
ap_mpm_pod_killpg(pod[i], i, retained->max_daemons_limit); |
|
|
1234 |
} |
1201 |
/* This is mostly for debugging... so that we know what is still |
1235 |
/* This is mostly for debugging... so that we know what is still |
1202 |
* gracefully dealing with existing request. This will break |
1236 |
* gracefully dealing with existing request. This will break |
1203 |
* in a very nasty way if we ever have the scoreboard totally |
1237 |
* in a very nasty way if we ever have the scoreboard totally |
Lines 1238-1243
Link Here
|
1238 |
{ |
1272 |
{ |
1239 |
int startup = 0; |
1273 |
int startup = 0; |
1240 |
int level_flags = 0; |
1274 |
int level_flags = 0; |
|
|
1275 |
int i; |
1276 |
int num_of_cores = 0; |
1277 |
ap_listen_rec *lr; |
1241 |
apr_status_t rv; |
1278 |
apr_status_t rv; |
1242 |
|
1279 |
|
1243 |
pconf = p; |
1280 |
pconf = p; |
Lines 1248-1265
Link Here
|
1248 |
level_flags |= APLOG_STARTUP; |
1285 |
level_flags |= APLOG_STARTUP; |
1249 |
} |
1286 |
} |
1250 |
|
1287 |
|
|
|
1288 |
flag = 0; /* do not bind and listen to ap_listeners */ |
1251 |
if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { |
1289 |
if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { |
1252 |
ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0, |
1290 |
ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0, |
1253 |
(startup ? NULL : s), |
1291 |
(startup ? NULL : s), |
1254 |
"no listening sockets available, shutting down"); |
1292 |
"no listening sockets available, shutting down"); |
1255 |
return DONE; |
1293 |
return DONE; |
1256 |
} |
1294 |
} |
1257 |
|
1295 |
#ifdef HAVE_SO_REUSEPORT |
1258 |
if ((rv = ap_mpm_pod_open(pconf, &pod))) { |
1296 |
num_of_cores = sysconf(_SC_NPROCESSORS_ONLN); |
1259 |
ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv, |
1297 |
if (num_of_cores > 8) { |
1260 |
(startup ? NULL : s), |
1298 |
num_buckets = sysconf(_SC_NPROCESSORS_ONLN)/8; |
1261 |
"could not open pipe-of-death"); |
1299 |
} |
1262 |
return DONE; |
1300 |
else { |
|
|
1301 |
num_buckets = 1; |
1302 |
} |
1303 |
#else |
1304 |
if (num_listensocks > 1) { |
1305 |
num_buckets = num_listensocks; |
1306 |
num_listensocks = 1; /* partition the listener into different bucket */ |
1307 |
} |
1308 |
#endif |
1309 |
ap_post_config_listeners(ap_server_conf, pconf, num_buckets); |
1310 |
|
1311 |
for (lr = ap_listeners; lr; lr=lr->next) { |
1312 |
apr_socket_close(lr->sd); |
1313 |
} |
1314 |
|
1315 |
pod = apr_palloc(pconf, sizeof(ap_pod_t *) * num_buckets); |
1316 |
for (i = 0; i < num_buckets; i++) { |
1317 |
if ((rv = ap_mpm_pod_open(pconf, &pod[i]))) { |
1318 |
ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv, |
1319 |
(startup ? NULL : s), |
1320 |
"could not open pipe-of-death"); |
1321 |
return DONE; |
1322 |
} |
1263 |
} |
1323 |
} |
1264 |
return OK; |
1324 |
return OK; |
1265 |
} |
1325 |
} |
Lines 1292-1298
Link Here
|
1292 |
if (!retained) { |
1352 |
if (!retained) { |
1293 |
retained = ap_retained_data_create(userdata_key, sizeof(*retained)); |
1353 |
retained = ap_retained_data_create(userdata_key, sizeof(*retained)); |
1294 |
retained->max_daemons_limit = -1; |
1354 |
retained->max_daemons_limit = -1; |
1295 |
retained->idle_spawn_rate = 1; |
1355 |
int i; |
|
|
1356 |
for (i = 0; i < 1025; i++) { |
1357 |
retained->idle_spawn_rate[i] = 1; |
1358 |
} |
1296 |
} |
1359 |
} |
1297 |
++retained->module_loads; |
1360 |
++retained->module_loads; |
1298 |
if (retained->module_loads == 2) { |
1361 |
if (retained->module_loads == 2) { |