diff options
31 files changed, 460 insertions, 342 deletions
@@ -1,4 +1,8 @@ Changes with Apache 2.0.30-dev + + *) Change core code to allow an MPM to set hard thread/server + limits at startup. [Jeff Trawick] + *) Win32: The async AcceptEx() event should be autoreset upon successful completion of a wait (WaitForSingleObject). This eliminates a number of spurious diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 558be523a6..cdf2a203c1 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -83,12 +83,15 @@ * 20011127 (2.0.29-dev) bump for postconfig hook change, and removal of socket * from connection record * 20011212 (2.0.30-dev) bump for new used_path_info member of request_rec + * 20011218 (2.0.30-dev) bump for new sbh member of conn_rec, different + * declarations for scoreboard, new parameter to + * create_connection hook */ #define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */ #ifndef MODULE_MAGIC_NUMBER_MAJOR -#define MODULE_MAGIC_NUMBER_MAJOR 20011212 +#define MODULE_MAGIC_NUMBER_MAJOR 20011218 #endif #define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */ #define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR /* backward compat */ diff --git a/include/http_connection.h b/include/http_connection.h index 57b043890c..5cf0ade10f 100644 --- a/include/http_connection.h +++ b/include/http_connection.h @@ -127,10 +127,11 @@ AP_DECLARE_HOOK(int,process_connection,(conn_rec *c)) * @param csd The socket that has been accepted * @param conn_id A unique identifier for this connection. The ID only * needs to be unique at that time, not forever. + * @param sbh A handle to scoreboard information for this connection. * @return An allocated connection record or NULL. */ AP_DECLARE_HOOK(conn_rec *, create_connection, - (apr_pool_t *p, server_rec *server, apr_socket_t *csd, int conn_id)) + (apr_pool_t *p, server_rec *server, apr_socket_t *csd, int conn_id, void *sbh)) #ifdef __cplusplus } diff --git a/include/httpd.h b/include/httpd.h index aca094ace9..fb1267cfd9 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -982,6 +982,8 @@ struct conn_rec { struct ap_filter_t *input_filters; /** A list of output filters to be used for this connection */ struct ap_filter_t *output_filters; + /** handle to scoreboard information for this connection */ + void *sbh; }; /* Per-vhost config... */ diff --git a/include/scoreboard.h b/include/scoreboard.h index 6f12fdd752..6b4effdecf 100644 --- a/include/scoreboard.h +++ b/include/scoreboard.h @@ -70,7 +70,6 @@ extern "C" { #endif #include "ap_config.h" -#include "mpm_default.h" /* For HARD_.*_LIMIT */ #include "apr_hooks.h" #include "apr_thread_proc.h" #include "apr_portable.h" @@ -185,8 +184,8 @@ struct process_score{ typedef struct { global_score global; - process_score parent[HARD_SERVER_LIMIT]; - worker_score servers[HARD_SERVER_LIMIT][HARD_THREAD_LIMIT]; + process_score *parent; + worker_score **servers; } scoreboard; #define KEY_LENGTH 16 @@ -196,11 +195,12 @@ typedef struct { char value[VALUE_LENGTH]; } status_table_entry; +/* XXX what should mod_ssl init use instead of this? */ #define SCOREBOARD_SIZE sizeof(scoreboard) AP_DECLARE(int) ap_exists_scoreboard_image(void); AP_DECLARE_NONSTD(void) ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e t); -AP_DECLARE(void) ap_increment_counts(int child_num, int thread_num, request_rec *r); +AP_DECLARE(void) ap_increment_counts(void *sbh, request_rec *r); apr_status_t ap_cleanup_scoreboard(void *d); @@ -208,9 +208,14 @@ AP_DECLARE(void) reopen_scoreboard(apr_pool_t *p); void ap_sync_scoreboard_image(void); +AP_DECLARE(void) ap_create_sb_handle(void **new_handle, apr_pool_t *p, + int child_num, int thread_num); + void update_scoreboard_global(void); AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid); -AP_DECLARE(int) ap_update_child_status(int child_num, int thread_num, int status, request_rec *r); +AP_DECLARE(int) ap_update_child_status(void *sbh, int status, request_rec *r); +AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, int thread_num, + int status, request_rec *r); void ap_time_process_request(int child_num, int thread_num, int status); AP_DECLARE(worker_score *) ap_get_servers_scoreboard(int x, int y); AP_DECLARE(process_score *) ap_get_parent_scoreboard(int x); diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 840d187cc4..80a23241a4 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -269,23 +269,23 @@ static int ap_process_http_connection(conn_rec *c) * until no requests are left or we decide to close. */ - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_BUSY_READ, NULL); + ap_update_child_status(c->sbh, SERVER_BUSY_READ, NULL); while ((r = ap_read_request(c)) != NULL) { c->keepalive = 0; /* process the request if it was read without error */ - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_BUSY_WRITE, r); + ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r); if (r->status == HTTP_OK) ap_process_request(r); if (ap_extended_status) - ap_increment_counts(AP_CHILD_THREAD_FROM_ID(c->id), r); + ap_increment_counts(c->sbh, r); if (!c->keepalive || c->aborted) break; - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_BUSY_KEEPALIVE, r); + ap_update_child_status(c->sbh, SERVER_BUSY_KEEPALIVE, r); apr_pool_destroy(r->pool); if (ap_graceful_stop_signalled()) diff --git a/server/connection.c b/server/connection.c index 1bc6c2bb1b..9a6f5928ed 100644 --- a/server/connection.c +++ b/server/connection.c @@ -83,8 +83,8 @@ APR_HOOK_STRUCT( AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c),(c),OK,DECLINED) AP_IMPLEMENT_HOOK_RUN_FIRST(int,process_connection,(conn_rec *c),(c),DECLINED) AP_IMPLEMENT_HOOK_RUN_FIRST(conn_rec *,create_connection, - (apr_pool_t *p, server_rec *server, apr_socket_t *csd, int conn_id), - (p, server, csd, conn_id), NULL) + (apr_pool_t *p, server_rec *server, apr_socket_t *csd, int conn_id, void *sbh), + (p, server, csd, conn_id, sbh), NULL) /* * More machine-dependent networking gooo... on some systems, @@ -167,7 +167,7 @@ AP_DECLARE(void) ap_lingering_close(conn_rec *c) return; } - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_CLOSING, NULL); + ap_update_child_status(c->sbh, SERVER_CLOSING, NULL); #ifdef NO_LINGCLOSE ap_flush_conn(c); /* just close it */ diff --git a/server/core.c b/server/core.c index a5097060b8..7a0c5e0bc3 100644 --- a/server/core.c +++ b/server/core.c @@ -3426,7 +3426,7 @@ static int core_create_proxy_req(request_rec *r, request_rec *pr) } static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server, - apr_socket_t *csd, int conn_id) + apr_socket_t *csd, int conn_id, void *sbh) { core_net_rec *net = apr_palloc(ptrans, sizeof(*net)); apr_status_t rv; @@ -3438,9 +3438,9 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server, net->in_ctx = NULL; net->out_ctx = NULL; net->c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec)); - - (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(conn_id), - SERVER_BUSY_READ, (request_rec *) NULL); + + net->c->sbh = sbh; + (void) ap_update_child_status(net->c->sbh, SERVER_BUSY_READ, (request_rec *) NULL); /* Got a connection structure, so initialize what fields we can * (the rest are zeroed out by pcalloc). diff --git a/server/mpm/beos/beos.c b/server/mpm/beos/beos.c index 484b473afc..1b21d92a62 100644 --- a/server/mpm/beos/beos.c +++ b/server/mpm/beos/beos.c @@ -81,12 +81,43 @@ #include <kernel/OS.h> #include "mpm_common.h" #include "mpm.h" +#include "mpm_default.h" #include <unistd.h> #include <sys/socket.h> #include <signal.h> extern int _kset_fd_limit_(int num); +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons: + * 1) in case something goes seriously wrong, we want to stop the server starting + * threads ad infinitum and crashing the server (remember that BeOS has a 192 + * thread per team limit). + * 2) it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ + +/* we only ever have 1 main process running... */ +#define HARD_SERVER_LIMIT 1 + +/* Limit on the threads per process. Clients will be locked out if more than + * this * HARD_SERVER_LIMIT are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifdef NO_THREADS +#define HARD_THREAD_LIMIT 1 +#endif +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 50 +#endif + /* * Actual definitions of config globals */ @@ -301,6 +332,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num) conn_rec *current_conn; long conn_id = my_child_num; int csd; + void *sbh; (void)apr_os_sock_get(&csd, sock); @@ -313,7 +345,8 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num) return; } - current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id); + ap_create_sb_handle(&sbh, p, 0, my_child_num); + current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn); @@ -352,8 +385,8 @@ static int32 worker_thread(void * dummy) worker_thread_count++; apr_lock_release(worker_thread_count_mutex); - (void) ap_update_child_status(0, child_slot, SERVER_STARTING, - (request_rec*)NULL); + (void) ap_update_child_status_from_indexes(0, child_slot, SERVER_STARTING, + (request_rec*)NULL); apr_poll_setup(&pollset, num_listening_sockets, tpool); for(n=0 ; n <= num_listening_sockets ; n++) @@ -369,8 +402,8 @@ static int32 worker_thread(void * dummy) if (this_worker_should_exit) break; - (void) ap_update_child_status(0, child_slot, SERVER_READY, - (request_rec*)NULL); + (void) ap_update_child_status_from_indexes(0, child_slot, SERVER_READY, + (request_rec*)NULL); apr_lock_acquire(accept_mutex); @@ -457,7 +490,7 @@ static int32 worker_thread(void * dummy) apr_pool_clear(ptrans); } - ap_update_child_status(0, child_slot, SERVER_DEAD, (request_rec*)NULL); + ap_update_child_status_from_indexes(0, child_slot, SERVER_DEAD, (request_rec*)NULL); ap_log_error(APLOG_MARK, APLOG_NOTICE | APLOG_NOERRNO, 0, NULL, "worker_thread %ld exiting", find_thread(NULL)); @@ -492,7 +525,7 @@ static int make_worker(int slot) return 0; } - (void) ap_update_child_status(0, slot, SERVER_STARTING, (request_rec*)NULL); + (void) ap_update_child_status_from_indexes(0, slot, SERVER_STARTING, (request_rec*)NULL); tid = spawn_thread(worker_thread, "apache_worker", B_NORMAL_PRIORITY, my_info); if (tid < B_NO_ERROR) { @@ -502,8 +535,8 @@ static int make_worker(int slot) * Apache running away with the CPU trying to fork over and * over and over again. */ - (void) ap_update_child_status(0, slot, SERVER_DEAD, - (request_rec*)NULL); + (void) ap_update_child_status_from_indexes(0, slot, SERVER_DEAD, + (request_rec*)NULL); sleep(10); free(my_info); @@ -627,7 +660,9 @@ static void server_main_loop(int remaining_threads_to_start) } if (child_slot >= 0) { ap_scoreboard_image->servers[0][child_slot].tid = 0; - (void) ap_update_child_status(0, child_slot, SERVER_DEAD, (request_rec*)NULL); + (void) ap_update_child_status_from_indexes(0, child_slot, + SERVER_DEAD, + (request_rec*)NULL); if (remaining_threads_to_start && child_slot < ap_thread_limit) { diff --git a/server/mpm/beos/mpm_default.h b/server/mpm/beos/mpm_default.h index 6de2bb39aa..043f77f691 100644 --- a/server/mpm/beos/mpm_default.h +++ b/server/mpm/beos/mpm_default.h @@ -71,36 +71,6 @@ #define DEFAULT_START_THREADS 10 #endif -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons: - * 1) in case something goes seriously wrong, we want to stop the server starting - * threads ad infinitum and crashing the server (remember that BeOS has a 192 - * thread per team limit). - * 2) it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ - -/* we only ever have 1 main process running... */ -#define HARD_SERVER_LIMIT 1 - -/* Limit on the threads per process. Clients will be locked out if more than - * this * HARD_SERVER_LIMIT are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifdef NO_THREADS -#define HARD_THREAD_LIMIT 1 -#endif -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 50 -#endif - #ifdef NO_THREADS #define DEFAULT_THREADS 1 #endif diff --git a/server/mpm/experimental/perchild/mpm.h b/server/mpm/experimental/perchild/mpm.h index c1bbf0ae8f..646a6aeae3 100644 --- a/server/mpm/experimental/perchild/mpm.h +++ b/server/mpm/experimental/perchild/mpm.h @@ -93,7 +93,6 @@ typedef struct ap_ctable{ extern int ap_threads_per_child; extern int ap_max_daemons_limit; -extern ap_ctable ap_child_table[HARD_SERVER_LIMIT]; extern server_rec *ap_server_conf; #endif /* APACHE_MPM_PERCHILD_H */ diff --git a/server/mpm/experimental/perchild/mpm_default.h b/server/mpm/experimental/perchild/mpm_default.h index f462ea8f90..46fb097701 100644 --- a/server/mpm/experimental/perchild/mpm_default.h +++ b/server/mpm/experimental/perchild/mpm_default.h @@ -59,9 +59,6 @@ #ifndef APACHE_MPM_DEFAULT_H #define APACHE_MPM_DEFAULT_H -#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) -#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_LIMIT), (i % HARD_THREAD_LIMIT) - /* Number of threads to spawn off by default --- also, if fewer than * this free when the caretaker checks, it will spawn more. */ @@ -83,38 +80,12 @@ #define DEFAULT_MIN_SPARE_THREAD 5 #endif -/* Limit on the threads per process. Clients will be locked out if more than - * this * HARD_SERVER_LIMIT are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 64 -#endif - /* Number of servers to spawn off by default */ #ifndef DEFAULT_NUM_DAEMON #define DEFAULT_NUM_DAEMON 2 #endif -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_SERVER_LIMIT -#define HARD_SERVER_LIMIT 8 -#endif - /* File used for accept locking, when we use a file */ #ifndef DEFAULT_LOCKFILE #define DEFAULT_LOCKFILE "logs/accept.lock" diff --git a/server/mpm/experimental/perchild/perchild.c b/server/mpm/experimental/perchild/perchild.c index fb83a84a1f..c7693d1f15 100644 --- a/server/mpm/experimental/perchild/perchild.c +++ b/server/mpm/experimental/perchild/perchild.c @@ -107,6 +107,35 @@ #include <sys/processor.h> /* for bindprocessor() */ #endif +#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) +#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_LIMIT), (i % HARD_THREAD_LIMIT) + +/* Limit on the threads per process. Clients will be locked out if more than + * this * HARD_SERVER_LIMIT are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 64 +#endif + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_SERVER_LIMIT +#define HARD_SERVER_LIMIT 8 +#endif + /* * Actual definitions of config globals */ @@ -496,6 +525,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id) int csd; apr_status_t rv; int thread_num = conn_id % HARD_THREAD_LIMIT; + void *sbh; if ((rv = apr_os_sock_get(&csd, sock)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_os_sock_get"); @@ -515,7 +545,8 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id) ap_sock_disable_nagle(sock); } - current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id); + ap_create_sb_handle(&sbh, p, conn_id / HARD_SERVER_LIMIT, thread_num); + current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn); ap_lingering_close(current_conn); @@ -613,8 +644,9 @@ static void *worker_thread(apr_thread_t *thd, void *arg) apr_lock_release(thread_pool_parent_mutex); apr_pool_create(&ptrans, tpool); - (void) ap_update_child_status(child_num, thread_num, SERVER_STARTING, - (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(child_num, thread_num, + SERVER_STARTING, + (request_rec *) NULL); apr_poll_setup(&pollset, num_listenfds+1, tpool); for(n = 0; n <= num_listenfds; ++n) { @@ -640,8 +672,9 @@ static void *worker_thread(apr_thread_t *thd, void *arg) thread_just_started = 0; } - (void) ap_update_child_status(child_num, thread_num, SERVER_READY, - (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(child_num, thread_num, + SERVER_READY, + (request_rec *) NULL); apr_lock_acquire(thread_accept_mutex); if (workers_may_exit) { @@ -793,8 +826,8 @@ static void *worker_thread(apr_thread_t *thd, void *arg) } apr_lock_acquire(thread_pool_parent_mutex); - ap_update_child_status(child_num, thread_num, SERVER_DEAD, - (request_rec *) NULL); + ap_update_child_status_from_indexes(child_num, thread_num, SERVER_DEAD, + (request_rec *) NULL); apr_pool_destroy(tpool); apr_lock_release(thread_pool_parent_mutex); apr_lock_acquire(worker_thread_count_mutex); @@ -995,8 +1028,8 @@ static int make_child(server_rec *s, int slot) ap_child_table[slot].status = SERVER_ALIVE; child_main(slot); } - (void) ap_update_child_status(slot, 0, SERVER_STARTING, - (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, + (request_rec *) NULL); if ((pid = fork()) == -1) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, @@ -1142,8 +1175,8 @@ static void server_main_loop(int remaining_children_to_start) } if (child_slot >= 0) { ap_child_table[child_slot].pid = 0; - ap_update_child_status(child_slot, i, SERVER_DEAD, - (request_rec *) NULL); + ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, + (request_rec *) NULL); if (remaining_children_to_start diff --git a/server/mpm/mpmt_os2/mpm_default.h b/server/mpm/mpmt_os2/mpm_default.h index 100beb2e61..67fbab0575 100644 --- a/server/mpm/mpmt_os2/mpm_default.h +++ b/server/mpm/mpmt_os2/mpm_default.h @@ -65,17 +65,6 @@ #define DEFAULT_START_DAEMON 2 #endif -/* We don't need many processes, - * they're only for redundancy in the event of a crash - */ -#define HARD_SERVER_LIMIT 10 - -/* Limit on the total number of threads per process - */ -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 256 -#endif - /* Maximum number of *free* server threads --- more than this, and * they will die off. */ @@ -109,8 +98,4 @@ #define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 #endif -/* AP_CHILD_THREAD_FROM_ID is used by the scoreboard. */ -#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_LIMIT), (i % HARD_THREAD_LIMIT) -#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) - #endif /* AP_MPM_DEFAULT_H */ diff --git a/server/mpm/mpmt_os2/mpmt_os2.c b/server/mpm/mpmt_os2/mpmt_os2.c index 7d04a104fc..6bb83b97da 100644 --- a/server/mpm/mpmt_os2/mpmt_os2.c +++ b/server/mpm/mpmt_os2/mpmt_os2.c @@ -100,6 +100,17 @@ #include <os2.h> #include <process.h> +/* We don't need many processes, + * they're only for redundancy in the event of a crash + */ +#define HARD_SERVER_LIMIT 10 + +/* Limit on the total number of threads per process + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 256 +#endif + server_rec *ap_server_conf; static apr_pool_t *pconf = NULL; /* Pool for config stuff */ static const char *ap_pid_fname=NULL; diff --git a/server/mpm/mpmt_os2/mpmt_os2_child.c b/server/mpm/mpmt_os2/mpmt_os2_child.c index 7e258d2695..8a25299573 100644 --- a/server/mpm/mpmt_os2/mpmt_os2_child.c +++ b/server/mpm/mpmt_os2/mpmt_os2_child.c @@ -78,6 +78,21 @@ #include <os2.h> #include <process.h> +/* XXXXXX move these to header file private to this MPM */ + +/* We don't need many processes, + * they're only for redundancy in the event of a crash + */ +#define HARD_SERVER_LIMIT 10 + +/* Limit on the total number of threads per process + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 256 +#endif + +#define ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) + typedef struct { apr_pool_t *pconn; apr_socket_t *conn_sd; @@ -387,6 +402,7 @@ static void worker_main(void *vpArg) BYTE priority; int thread_slot = (int)vpArg; EXCEPTIONREGISTRATIONRECORD reg_rec = { NULL, thread_exception_handler }; + void *sbh; /* Trap exceptions in this thread so we don't take down the whole process */ DosSetExceptionHandler( ®_rec ); @@ -400,12 +416,14 @@ static void worker_main(void *vpArg) ap_scoreboard_image->servers[child_slot][thread_slot].tid = 0; } - conn_id = AP_ID_FROM_CHILD_THREAD(child_slot, thread_slot); - ap_update_child_status(child_slot, thread_slot, SERVER_READY, NULL); + conn_id = ID_FROM_CHILD_THREAD(child_slot, thread_slot); + ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_READY, + NULL); while (rc = DosReadQueue(workq, &rd, &len, (PPVOID)&worker_args, 0, DCWW_WAIT, &priority, NULLHANDLE), rc == 0 && rd.ulData != WORKTYPE_EXIT) { pconn = worker_args->pconn; + ap_create_sb_handle(&sbh, pconn, child_slot, thread_slot); current_conn = ap_run_create_connection(pconn, ap_server_conf, worker_args->conn_sd, conn_id); if (current_conn) { @@ -414,10 +432,12 @@ static void worker_main(void *vpArg) } apr_pool_destroy(pconn); - ap_update_child_status(child_slot, thread_slot, SERVER_READY, NULL); + ap_update_child_status_from_indexes(child_slot, thread_slot, + SERVER_READY, NULL); } - ap_update_child_status(child_slot, thread_slot, SERVER_DEAD, NULL); + ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_DEAD, + NULL); } diff --git a/server/mpm/netware/mpm_default.h b/server/mpm/netware/mpm_default.h index 7d4bfba42a..05abdf01f3 100644 --- a/server/mpm/netware/mpm_default.h +++ b/server/mpm/netware/mpm_default.h @@ -59,9 +59,6 @@ #ifndef APACHE_MPM_DEFAULT_H #define APACHE_MPM_DEFAULT_H -#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) -#define AP_CHILD_THREAD_FROM_ID(i) (0), (i) - /* Number of servers to spawn off by default --- also, if fewer than * this free when the caretaker checks, it will spawn more. */ @@ -83,32 +80,6 @@ #define DEFAULT_MIN_FREE_DAEMON 1 #endif -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_SERVER_LIMIT -#define HARD_SERVER_LIMIT 1 -#endif - -/* Limit on the threads per process. Clients will be locked out if more than - * this * HARD_SERVER_LIMIT are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 2048 -#endif - #ifndef DEFAULT_THREADS_PER_CHILD #define DEFAULT_THREADS_PER_CHILD 50 #endif diff --git a/server/mpm/netware/mpm_netware.c b/server/mpm/netware/mpm_netware.c index 2dccde33e1..60d69cf249 100644 --- a/server/mpm/netware/mpm_netware.c +++ b/server/mpm/netware/mpm_netware.c @@ -125,6 +125,32 @@ #include <nks/netware.h> #include <library.h> +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_SERVER_LIMIT +#define HARD_SERVER_LIMIT 1 +#endif + +/* Limit on the threads per process. Clients will be locked out if more than + * this * HARD_SERVER_LIMIT are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 2048 +#endif + #define WORKER_DEAD SERVER_DEAD #define WORKER_STARTING SERVER_STARTING #define WORKER_READY SERVER_READY @@ -193,7 +219,8 @@ static void clean_child_exit(int code, int worker_num) worker_thread_count--; apr_thread_mutex_unlock(worker_thread_count_mutex); if (worker_num >=0) - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(worker_num), WORKER_DEAD, (request_rec *) NULL); + ap_update_child_status_from_indexes(0, worker_num, WORKER_DEAD, + (request_rec *) NULL); NXThreadExit((void*)&code); } @@ -337,6 +364,7 @@ static void worker_main(void *arg) int sockdes; int worker_num_arg = (int)arg; apr_pollfd_t *listen_poll; + void *sbh; int my_worker_num = worker_num_arg; apr_socket_t *csd = NULL; @@ -358,7 +386,8 @@ static void worker_main(void *arg) clean_child_exit(1, my_worker_num); } - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_worker_num), WORKER_READY, (request_rec *) NULL); + ap_update_child_status_from_indexes(0, my_worker_num, WORKER_READY, + (request_rec *) NULL); while (!die_now) { /* @@ -372,7 +401,8 @@ static void worker_main(void *arg) clean_child_exit(0, my_worker_num); } - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_worker_num), WORKER_READY, (request_rec *) NULL); + ap_update_child_status_from_indexes(0, my_worker_num, WORKER_READY, + (request_rec *) NULL); /* * Wait for an acceptable connection to arrive. @@ -501,11 +531,13 @@ got_listener: apr_thread_mutex_unlock(accept_mutex); + ap_create_sb_handle(&sbh, ptrans, 0, my_worker_num); /* * We now have a connection, so set it up with the appropriate * socket options, file descriptors, and read/write buffers. */ - current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_worker_num); + current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, + my_worker_num, sbh); if (current_conn) { ap_process_connection(current_conn); ap_lingering_close(current_conn); @@ -526,7 +558,8 @@ static int make_child(server_rec *s, int slot) ap_max_workers_limit = slot + 1; } - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), WORKER_STARTING, (request_rec *) NULL); + ap_update_child_status_from_indexes(0, slot, WORKER_STARTING, + (request_rec *) NULL); if (ctx = NXContextAlloc((void (*)(void *)) worker_main, (void*)slot, NX_PRIO_MED, ap_thread_stack_size, NX_CTX_NORMAL, &err)) { char threadName[32]; @@ -543,7 +576,8 @@ static int make_child(server_rec *s, int slot) /* create thread didn't succeed. Fix the scoreboard or else * it will say SERVER_STARTING forever and ever */ - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), WORKER_DEAD, (request_rec *) NULL); + ap_update_child_status_from_indexes(0, slot, WORKER_DEAD, + (request_rec *) NULL); /* In case system resources are maxxed out, we don't want Apache running away with the CPU trying to fork over and @@ -655,7 +689,8 @@ static void perform_idle_server_maintenance(apr_pool_t *p) * while we were counting */ idle_spawn_rate = 1; - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(last_non_dead), WORKER_IDLE_KILL, (request_rec *) NULL); + ap_update_child_status_from_indexes(0, last_non_dead, WORKER_IDLE_KILL, + (request_rec *) NULL); DBPRINT1("\nKilling idle thread: %d\n", last_non_dead); } else if (idle_count < ap_threads_min_free) { diff --git a/server/mpm/perchild/mpm.h b/server/mpm/perchild/mpm.h index c1bbf0ae8f..646a6aeae3 100644 --- a/server/mpm/perchild/mpm.h +++ b/server/mpm/perchild/mpm.h @@ -93,7 +93,6 @@ typedef struct ap_ctable{ extern int ap_threads_per_child; extern int ap_max_daemons_limit; -extern ap_ctable ap_child_table[HARD_SERVER_LIMIT]; extern server_rec *ap_server_conf; #endif /* APACHE_MPM_PERCHILD_H */ diff --git a/server/mpm/perchild/mpm_default.h b/server/mpm/perchild/mpm_default.h index f462ea8f90..46fb097701 100644 --- a/server/mpm/perchild/mpm_default.h +++ b/server/mpm/perchild/mpm_default.h @@ -59,9 +59,6 @@ #ifndef APACHE_MPM_DEFAULT_H #define APACHE_MPM_DEFAULT_H -#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) -#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_LIMIT), (i % HARD_THREAD_LIMIT) - /* Number of threads to spawn off by default --- also, if fewer than * this free when the caretaker checks, it will spawn more. */ @@ -83,38 +80,12 @@ #define DEFAULT_MIN_SPARE_THREAD 5 #endif -/* Limit on the threads per process. Clients will be locked out if more than - * this * HARD_SERVER_LIMIT are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 64 -#endif - /* Number of servers to spawn off by default */ #ifndef DEFAULT_NUM_DAEMON #define DEFAULT_NUM_DAEMON 2 #endif -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_SERVER_LIMIT -#define HARD_SERVER_LIMIT 8 -#endif - /* File used for accept locking, when we use a file */ #ifndef DEFAULT_LOCKFILE #define DEFAULT_LOCKFILE "logs/accept.lock" diff --git a/server/mpm/perchild/perchild.c b/server/mpm/perchild/perchild.c index fb83a84a1f..c7693d1f15 100644 --- a/server/mpm/perchild/perchild.c +++ b/server/mpm/perchild/perchild.c @@ -107,6 +107,35 @@ #include <sys/processor.h> /* for bindprocessor() */ #endif +#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) +#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_LIMIT), (i % HARD_THREAD_LIMIT) + +/* Limit on the threads per process. Clients will be locked out if more than + * this * HARD_SERVER_LIMIT are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 64 +#endif + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_SERVER_LIMIT +#define HARD_SERVER_LIMIT 8 +#endif + /* * Actual definitions of config globals */ @@ -496,6 +525,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id) int csd; apr_status_t rv; int thread_num = conn_id % HARD_THREAD_LIMIT; + void *sbh; if ((rv = apr_os_sock_get(&csd, sock)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_os_sock_get"); @@ -515,7 +545,8 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id) ap_sock_disable_nagle(sock); } - current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id); + ap_create_sb_handle(&sbh, p, conn_id / HARD_SERVER_LIMIT, thread_num); + current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn); ap_lingering_close(current_conn); @@ -613,8 +644,9 @@ static void *worker_thread(apr_thread_t *thd, void *arg) apr_lock_release(thread_pool_parent_mutex); apr_pool_create(&ptrans, tpool); - (void) ap_update_child_status(child_num, thread_num, SERVER_STARTING, - (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(child_num, thread_num, + SERVER_STARTING, + (request_rec *) NULL); apr_poll_setup(&pollset, num_listenfds+1, tpool); for(n = 0; n <= num_listenfds; ++n) { @@ -640,8 +672,9 @@ static void *worker_thread(apr_thread_t *thd, void *arg) thread_just_started = 0; } - (void) ap_update_child_status(child_num, thread_num, SERVER_READY, - (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(child_num, thread_num, + SERVER_READY, + (request_rec *) NULL); apr_lock_acquire(thread_accept_mutex); if (workers_may_exit) { @@ -793,8 +826,8 @@ static void *worker_thread(apr_thread_t *thd, void *arg) } apr_lock_acquire(thread_pool_parent_mutex); - ap_update_child_status(child_num, thread_num, SERVER_DEAD, - (request_rec *) NULL); + ap_update_child_status_from_indexes(child_num, thread_num, SERVER_DEAD, + (request_rec *) NULL); apr_pool_destroy(tpool); apr_lock_release(thread_pool_parent_mutex); apr_lock_acquire(worker_thread_count_mutex); @@ -995,8 +1028,8 @@ static int make_child(server_rec *s, int slot) ap_child_table[slot].status = SERVER_ALIVE; child_main(slot); } - (void) ap_update_child_status(slot, 0, SERVER_STARTING, - (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, + (request_rec *) NULL); if ((pid = fork()) == -1) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, @@ -1142,8 +1175,8 @@ static void server_main_loop(int remaining_children_to_start) } if (child_slot >= 0) { ap_child_table[child_slot].pid = 0; - ap_update_child_status(child_slot, i, SERVER_DEAD, - (request_rec *) NULL); + ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, + (request_rec *) NULL); if (remaining_children_to_start diff --git a/server/mpm/prefork/mpm_default.h b/server/mpm/prefork/mpm_default.h index 3763037ae6..3854a2bc23 100644 --- a/server/mpm/prefork/mpm_default.h +++ b/server/mpm/prefork/mpm_default.h @@ -59,10 +59,6 @@ #ifndef APACHE_MPM_DEFAULT_H #define APACHE_MPM_DEFAULT_H -#define AP_ID_FROM_CHILD_THREAD(c, t) c -#define AP_CHILD_THREAD_FROM_ID(i) i, 0 - - /* Number of servers to spawn off by default --- also, if fewer than * this free when the caretaker checks, it will spawn more. */ @@ -84,25 +80,6 @@ #define DEFAULT_MIN_FREE_DAEMON 5 #endif -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_SERVER_LIMIT -#define HARD_SERVER_LIMIT 256 -#endif - -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 1 -#endif - /* File used for accept locking, when we use a file */ #ifndef DEFAULT_LOCKFILE #define DEFAULT_LOCKFILE "logs/accept.lock" diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index b33292b1e7..30587fb0a2 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -103,6 +103,25 @@ #include <signal.h> #include <sys/times.h> +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_SERVER_LIMIT +#define HARD_SERVER_LIMIT 256 +#endif + +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 1 +#endif + /* config globals */ int ap_threads_per_child=0; /* Worker threads per child */ @@ -343,7 +362,7 @@ int reap_children(int *exitcode, apr_exit_why_e *status) ap_sync_scoreboard_image(); if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD && kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) { - ap_update_child_status(AP_CHILD_THREAD_FROM_ID(n), SERVER_DEAD, NULL); + ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL); /* just mark it as having a successful exit status */ *status = APR_PROC_EXIT; *exitcode = 0; @@ -549,6 +568,7 @@ static void child_main(int child_num_arg) apr_pollfd_t *pollset; int offset; void *csd; + void *sbh; my_child_num = child_num_arg; ap_my_pid = getpid(); @@ -572,7 +592,9 @@ static void child_main(int child_num_arg) ap_run_child_init(pchild, ap_server_conf); - (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_READY, (request_rec *) NULL); + ap_create_sb_handle(&sbh, pchild, my_child_num, 0); + + (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); ap_sync_scoreboard_image(); @@ -602,7 +624,7 @@ static void child_main(int child_num_arg) clean_child_exit(0); } - (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_READY, (request_rec *) NULL); + (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); /* * Wait for an acceptable connection to arrive. @@ -679,7 +701,7 @@ static void child_main(int child_num_arg) * socket options, file descriptors, and read/write buffers. */ - current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num); + current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh); if (current_conn) { ap_process_connection(current_conn); ap_lingering_close(current_conn); @@ -720,7 +742,8 @@ static int make_child(server_rec *s, int slot) child_main(slot); } - (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), SERVER_STARTING, (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, + (request_rec *) NULL); #ifdef _OSD_POSIX @@ -736,7 +759,8 @@ static int make_child(server_rec *s, int slot) /* fork didn't succeed. Fix the scoreboard or else * it will say SERVER_STARTING forever and ever */ - (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), SERVER_DEAD, (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, + (request_rec *) NULL); /* In case system resources are maxxed out, we don't want Apache running away with the CPU trying to fork over and @@ -1029,8 +1053,8 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) ap_sync_scoreboard_image(); child_slot = find_child_by_pid(&pid); if (child_slot >= 0) { - (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(child_slot), SERVER_DEAD, - (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD, + (request_rec *) NULL); if (remaining_children_to_start && child_slot < ap_daemons_limit) { /* we're still doing a 1-for-1 replacement of dead diff --git a/server/mpm/spmt_os2/mpm_default.h b/server/mpm/spmt_os2/mpm_default.h index c554fddf60..54cd83c3d6 100644 --- a/server/mpm/spmt_os2/mpm_default.h +++ b/server/mpm/spmt_os2/mpm_default.h @@ -80,24 +80,6 @@ #define DEFAULT_MIN_FREE_DAEMON 5 #endif -/* SPMT_OS2 only ever has 1 process */ -#define HARD_SERVER_LIMIT 1 - -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 256 -#endif - /* Where the main/parent process's pid is logged */ #ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG "logs/httpd.pid" @@ -117,7 +99,4 @@ #define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 #endif -/* AP_CHILD_THREAD_FROM_ID is used by the scoreboard. */ -#define AP_CHILD_THREAD_FROM_ID(i) 0, i - #endif /* AP_MPM_DEFAULT_H */ diff --git a/server/mpm/spmt_os2/spmt_os2.c b/server/mpm/spmt_os2/spmt_os2.c index 350d852415..b5b1f498b7 100644 --- a/server/mpm/spmt_os2/spmt_os2.c +++ b/server/mpm/spmt_os2/spmt_os2.c @@ -82,6 +82,24 @@ #include <time.h> #include <io.h> +/* SPMT_OS2 only ever has 1 process */ +#define HARD_SERVER_LIMIT 1 + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 256 +#endif + /* config globals */ static int ap_daemons_to_start=0; @@ -489,6 +507,7 @@ static void thread_main(void *thread_num_arg) apr_pollfd_t *listen_poll; apr_socket_t *csd = NULL; int nsds, rv; + void *sbh; /* Disable the restart signal handlers and enable the just_die stuff. * Note that since restart() just notes that a restart has been @@ -519,7 +538,9 @@ static void thread_main(void *thread_num_arg) ap_run_child_init(pchild, ap_server_conf); - (void) ap_update_child_status(0, THREAD_GLOBAL(thread_num), SERVER_READY, (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(0, THREAD_GLOBAL(thread_num), + SERVER_READY, + (request_rec *) NULL); signal(SIGHUP, just_die); @@ -548,7 +569,9 @@ static void thread_main(void *thread_num_arg) clean_child_exit(0); } - (void) ap_update_child_status(0, THREAD_GLOBAL(thread_num), SERVER_READY, (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(0, THREAD_GLOBAL(thread_num), + SERVER_READY, + (request_rec *) NULL); /* * Wait for an acceptable connection to arrive. @@ -674,6 +697,7 @@ static void thread_main(void *thread_num_arg) */ signal(SIGUSR1, SIG_IGN); + ap_create_sb_handle(&sbh, ptrans, 0, THREAD_GLOBAL(thread_num)); /* * We now have a connection, so set it up with the appropriate * socket options, file descriptors, and read/write buffers. @@ -711,7 +735,8 @@ static int make_child(server_rec *s, int slot) *ppthread_globals = parent_globals; } - ap_update_child_status(0, slot, SERVER_STARTING, (request_rec *) NULL); + ap_update_child_status_from_indexes(0, slot, SERVER_STARTING, + (request_rec *) NULL); if ((tid = _beginthread(thread_main, NULL, 256*1024, (void *)slot)) == -1) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s, "_beginthread: Unable to create new thread"); @@ -719,7 +744,8 @@ static int make_child(server_rec *s, int slot) /* _beginthread didn't succeed. Fix the scoreboard or else * it will say SERVER_STARTING forever and ever */ - (void) ap_update_child_status(0, slot, SERVER_DEAD, (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(0, slot, SERVER_DEAD, + (request_rec *) NULL); /* In case system resources are maxxed out, we don't want Apache running away with the CPU trying to _beginthread over and @@ -1007,8 +1033,9 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) /* non-fatal death... note that it's gone in the scoreboard. */ thread_slot = find_thread_by_tid(tid); if (thread_slot >= 0) { - (void) ap_update_child_status(0, thread_slot, SERVER_DEAD, - (request_rec *) NULL); + (void) ap_update_child_status_from_indexes(0, thread_slot, + SERVER_DEAD, + (request_rec *) NULL); if (remaining_children_to_start && thread_slot < ap_daemons_limit) { /* we're still doing a 1-for-1 replacement of dead diff --git a/server/mpm/winnt/mpm_default.h b/server/mpm/winnt/mpm_default.h index 58275cfd8d..26f8e84d91 100644 --- a/server/mpm/winnt/mpm_default.h +++ b/server/mpm/winnt/mpm_default.h @@ -59,9 +59,6 @@ #ifndef APACHE_MPM_DEFAULT_H #define APACHE_MPM_DEFAULT_H -/* AP_CHILD_THREAD_FROM_ID is used by the scoreboard. */ -#define AP_CHILD_THREAD_FROM_ID(i) 0, i - /* Number of threads to spawn off by default --- also, if fewer than * this free when the caretaker checks, it will spawn more. */ @@ -83,36 +80,12 @@ #endif */ -/* Limit on the threads per process. Clients will be locked out if more than - * this * HARD_SERVER_LIMIT are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 4096 -#endif - /* Number of servers to spawn off by default */ #ifndef DEFAULT_NUM_DAEMON #define DEFAULT_NUM_DAEMON 1 #endif -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#define HARD_SERVER_LIMIT 1 - /* Where the main/parent process's pid is logged */ #ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG "logs/httpd.pid" diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index 4067d5ba1b..95d5012c24 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -75,6 +75,30 @@ #include "mpm_common.h" #include <malloc.h> +/* Limit on the threads per process. Clients will be locked out if more than + * this * HARD_SERVER_LIMIT are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 4096 +#endif + +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#define HARD_SERVER_LIMIT 1 + server_rec *ap_server_conf; typedef HANDLE thread; @@ -863,13 +887,14 @@ static void worker_main(int thread_num) static int requests_this_child = 0; PCOMP_CONTEXT context = NULL; apr_os_sock_info_t sockinfo; + void *sbh; while (1) { conn_rec *c; apr_int32_t disconnected; - ap_update_child_status(0, thread_num, SERVER_READY, - (request_rec *) NULL); + ap_update_child_status_from_indexes(0, thread_num, SERVER_READY, + (request_rec *) NULL); /* Grab a connection off the network */ @@ -900,8 +925,9 @@ static void worker_main(int thread_num) /* ### is this correct? Shouldn't be inheritable (at this point) */ apr_os_sock_make(&context->sock, &sockinfo, context->ptrans); + ap_create_sb_handle(&sbh, context->ptrans, 0, thread_num); c = ap_run_create_connection(context->ptrans, ap_server_conf, context->sock, - thread_num); + thread_num, sbh); if (c) { ap_process_connection(c); @@ -917,7 +943,8 @@ static void worker_main(int thread_num) } } - ap_update_child_status(0, thread_num, SERVER_DEAD, (request_rec *) NULL); + ap_update_child_status_from_indexes(0, thread_num, SERVER_DEAD, + (request_rec *) NULL); ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, ap_server_conf, "Child %d: Thread exiting.", my_pid); @@ -1023,7 +1050,8 @@ static void child_main() "Child %d: Starting %d worker threads.", my_pid, nthreads); child_handles = (thread) alloca(nthreads * sizeof(int)); for (i = 0; i < nthreads; i++) { - ap_update_child_status(0, i, SERVER_STARTING, (request_rec *) NULL); + ap_update_child_status_from_indexes(0, i, SERVER_STARTING, + (request_rec *) NULL); child_handles[i] = (thread) _beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE) worker_main, (void *) i, 0, &tid); } diff --git a/server/mpm/worker/mpm_default.h b/server/mpm/worker/mpm_default.h index 1d47cfe9b2..4b9ea3acb2 100644 --- a/server/mpm/worker/mpm_default.h +++ b/server/mpm/worker/mpm_default.h @@ -59,9 +59,6 @@ #ifndef APACHE_MPM_DEFAULT_H #define APACHE_MPM_DEFAULT_H -#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) -#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_LIMIT), (i % HARD_THREAD_LIMIT) - /* Number of servers to spawn off by default --- also, if fewer than * this free when the caretaker checks, it will spawn more. */ @@ -83,32 +80,6 @@ #define DEFAULT_MIN_FREE_DAEMON 3 #endif -/* Limit on the total --- clients will be locked out if more servers than - * this are needed. It is intended solely to keep the server from crashing - * when things get out of hand. - * - * We keep a hard maximum number of servers, for two reasons --- first off, - * in case something goes seriously wrong, we want to stop the fork bomb - * short of actually crashing the machine we're running on by filling some - * kernel table. Secondly, it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_SERVER_LIMIT -#define HARD_SERVER_LIMIT 16 -#endif - -/* Limit on the threads per process. Clients will be locked out if more than - * this * HARD_SERVER_LIMIT are needed. - * - * We keep this for one reason it keeps the size of the scoreboard file small - * enough that we can read the whole thing without worrying too much about - * the overhead. - */ -#ifndef HARD_THREAD_LIMIT -#define HARD_THREAD_LIMIT 64 -#endif - #ifndef DEFAULT_THREADS_PER_CHILD #define DEFAULT_THREADS_PER_CHILD 25 #endif diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index 3d28390d37..cb7e58f020 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -106,10 +106,37 @@ #include "ap_listen.h" #include "scoreboard.h" #include "fdqueue.h" +#include "mpm_default.h" #include <signal.h> #include <limits.h> /* for INT_MAX */ +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. + * + * We keep a hard maximum number of servers, for two reasons --- first off, + * in case something goes seriously wrong, we want to stop the fork bomb + * short of actually crashing the machine we're running on by filling some + * kernel table. Secondly, it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_SERVER_LIMIT +#define HARD_SERVER_LIMIT 16 +#endif + +/* Limit on the threads per process. Clients will be locked out if more than + * this * HARD_SERVER_LIMIT are needed. + * + * We keep this for one reason it keeps the size of the scoreboard file small + * enough that we can read the whole thing without worrying too much about + * the overhead. + */ +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 64 +#endif + /* * Actual definitions of config globals */ @@ -141,6 +168,8 @@ typedef struct { apr_threadattr_t *threadattr; } thread_starter; +#define ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t) + /* * The max child slot ever assigned, preserved across restarts. Necessary * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We @@ -495,9 +524,11 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num, int my_thread_num) { conn_rec *current_conn; - long conn_id = AP_ID_FROM_CHILD_THREAD(my_child_num, my_thread_num); + long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num); int csd; + void *sbh; + ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num); apr_os_sock_get(&csd, sock); if (csd >= FD_SETSIZE) { @@ -510,7 +541,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num, return; } - current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id); + current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh); if (current_conn) { ap_process_connection(current_conn); ap_lingering_close(current_conn); @@ -694,9 +725,9 @@ static void *listener_thread(apr_thread_t *thd, void * dummy) } } - ap_update_child_status(process_slot, thread_slot, - (dying) ? SERVER_DEAD : SERVER_GRACEFUL, - (request_rec *) NULL); + ap_update_child_status_from_indexes(process_slot, thread_slot, + (dying) ? SERVER_DEAD : SERVER_GRACEFUL, + (request_rec *) NULL); dying = 1; ap_scoreboard_image->parent[process_slot].quiescing = 1; kill(ap_my_pid, SIGTERM); @@ -718,9 +749,9 @@ static void *worker_thread(apr_thread_t *thd, void * dummy) free(ti); - ap_update_child_status(process_slot, thread_slot, SERVER_STARTING, NULL); + ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL); while (!workers_may_exit) { - ap_update_child_status(process_slot, thread_slot, SERVER_READY, NULL); + ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL); rv = ap_queue_pop(worker_queue, &csd, &ptrans); /* We get FD_QUEUE_EINTR whenever ap_queue_pop() has been interrupted * from an explicit call to ap_queue_interrupt_all(). This allows @@ -734,7 +765,7 @@ static void *worker_thread(apr_thread_t *thd, void * dummy) apr_pool_destroy(ptrans); } - ap_update_child_status(process_slot, thread_slot, + ap_update_child_status_from_indexes(process_slot, thread_slot, (dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL); apr_thread_mutex_lock(worker_thread_count_mutex); worker_thread_count--; @@ -797,7 +828,7 @@ static void *start_threads(apr_thread_t *thd, void *dummy) my_info->sd = 0; /* We are creating threads right now */ - ap_update_child_status(my_child_num, i, SERVER_STARTING, NULL); + ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, NULL); /* We let each thread update its own scoreboard entry. This is * done because it lets us deal with tid better. */ @@ -821,8 +852,8 @@ static void *start_threads(apr_thread_t *thd, void *dummy) /* What state should this child_main process be listed as in the * scoreboard...? - * ap_update_child_status(my_child_num, i, SERVER_STARTING, - * (request_rec *) NULL); + * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, + * (request_rec *) NULL); * * This state should be listed separately in the scoreboard, in some kind * of process_status, not mixed in with the worker threads' status. @@ -965,7 +996,7 @@ static int make_child(server_rec *s, int slot) /* fork didn't succeed. Fix the scoreboard or else * it will say SERVER_STARTING forever and ever */ - ap_update_child_status(slot, 0, SERVER_DEAD, NULL); + ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL); /* In case system resources are maxxed out, we don't want Apache running away with the CPU trying to fork over and @@ -1222,8 +1253,8 @@ static void server_main_loop(int remaining_children_to_start) child_slot = find_child_by_pid(&pid); if (child_slot >= 0) { for (i = 0; i < ap_threads_per_child; i++) - ap_update_child_status(child_slot, i, SERVER_DEAD, - (request_rec *) NULL); + ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD, + (request_rec *) NULL); ap_scoreboard_image->parent[child_slot].pid = 0; ap_scoreboard_image->parent[child_slot].quiescing = 0; diff --git a/server/mpm_common.c b/server/mpm_common.c index 57c3c037ac..0e474928b4 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -83,6 +83,7 @@ #include "mpm_common.h" #include "ap_mpm.h" #include "ap_listen.h" +#include "mpm_default.h" #ifdef AP_MPM_WANT_SET_SCOREBOARD #include "scoreboard.h" diff --git a/server/scoreboard.c b/server/scoreboard.c index f397900fe2..e1c3a54c91 100644 --- a/server/scoreboard.c +++ b/server/scoreboard.c @@ -97,6 +97,14 @@ AP_IMPLEMENT_HOOK_VOID(pre_mpm, (apr_pool_t *p, ap_scoreboard_e sb_type), (p, sb_type)) +typedef struct sb_handle { + int child_num; + int thread_num; +} sb_handle; + +static int server_limit, thread_limit; +static apr_size_t scoreboard_size; + /* * ToDo: * This function should be renamed to cleanup_shared @@ -115,6 +123,35 @@ static apr_status_t ap_cleanup_shared_mem(void *d) return APR_SUCCESS; } +static void calc_scoreboard_size(void) +{ + ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); + ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit); + scoreboard_size = sizeof(scoreboard); + scoreboard_size += sizeof(process_score) * server_limit; + scoreboard_size += sizeof(worker_score * ) * server_limit; + scoreboard_size += sizeof(worker_score) * server_limit * thread_limit; +} + +static void init_scoreboard(void) +{ + char *more_storage; + int i; + + memset(ap_scoreboard_image, 0, scoreboard_size); + more_storage = (char *)(ap_scoreboard_image + 1); + ap_scoreboard_image->parent = (process_score *)more_storage; + more_storage += sizeof(process_score) * server_limit; + ap_scoreboard_image->servers = (worker_score **)more_storage; + more_storage += server_limit * sizeof(worker_score *); + + for (i = 0; i < server_limit; i++) { + ap_scoreboard_image->servers[i] = (worker_score *)more_storage; + more_storage += thread_limit * sizeof(worker_score); + } + ap_assert(more_storage - (char *)ap_scoreboard_image == scoreboard_size); +} + /* ToDo: This function should be made to handle setting up * a scoreboard shared between processes using any IPC technique, * not just a shared memory segment @@ -128,14 +165,14 @@ static void setup_shared(apr_pool_t *p) apr_status_t rv; fname = ap_server_root_relative(p, ap_scoreboard_fname); - rv = apr_shm_init(&scoreboard_shm, SCOREBOARD_SIZE, fname, p); + rv = apr_shm_init(&scoreboard_shm, scoreboard_size, fname, p); if (rv != APR_SUCCESS) { apr_snprintf(buf, sizeof(buf), "%s: could not open(create) scoreboard: (%d)%s", ap_server_argv0, rv, apr_strerror(rv, errmsg, sizeof errmsg)); fprintf(stderr, "%s\n", buf); exit(APEXIT_INIT); } - ap_scoreboard_image = apr_shm_malloc(scoreboard_shm, SCOREBOARD_SIZE); + ap_scoreboard_image = apr_shm_malloc(scoreboard_shm, scoreboard_size); if (ap_scoreboard_image == NULL) { apr_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard", ap_server_argv0); @@ -143,7 +180,7 @@ static void setup_shared(apr_pool_t *p) apr_shm_destroy(scoreboard_shm); exit(APEXIT_INIT); } - ap_scoreboard_image->global.running_generation = 0; + /* everything will be cleared shortly */ #endif } @@ -180,13 +217,14 @@ AP_DECLARE_NONSTD(void) ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_t if (ap_scoreboard_image) running_gen = ap_scoreboard_image->global.running_generation; if (ap_scoreboard_image == NULL) { + calc_scoreboard_size(); if (sb_type == SB_SHARED) { setup_shared(p); } else { /* A simple malloc will suffice */ char buf[512]; - ap_scoreboard_image = (scoreboard *) malloc(SCOREBOARD_SIZE); + ap_scoreboard_image = (scoreboard *) malloc(scoreboard_size); if (ap_scoreboard_image == NULL) { apr_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard", ap_server_argv0); @@ -195,7 +233,7 @@ AP_DECLARE_NONSTD(void) ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_t } } } - memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE); + init_scoreboard(); /* can't just memset() */ ap_scoreboard_image->global.sb_type = sb_type; ap_scoreboard_image->global.running_generation = running_gen; ap_restart_time = apr_time_now(); @@ -242,11 +280,12 @@ void update_scoreboard_global(void) #endif } -AP_DECLARE(void) ap_increment_counts(int child_num, int thread_num, request_rec *r) +AP_DECLARE(void) ap_increment_counts(void *sbh, request_rec *r) { + sb_handle *sb = sbh; worker_score *ws; - ws = &ap_scoreboard_image->servers[child_num][thread_num]; + ws = &ap_scoreboard_image->servers[sb->child_num][sb->thread_num]; #ifdef HAVE_TIMES times(&ws->times); @@ -258,7 +297,7 @@ AP_DECLARE(void) ap_increment_counts(int child_num, int thread_num, request_rec ws->my_bytes_served += r->bytes_sent; ws->conn_bytes += r->bytes_sent; - put_scoreboard_info(child_num, thread_num, ws); + put_scoreboard_info(sb->child_num, sb->thread_num, ws); } AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid) @@ -275,7 +314,19 @@ AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid) return -1; } -AP_DECLARE(int) ap_update_child_status(int child_num, int thread_num, int status, request_rec *r) +AP_DECLARE(void) ap_create_sb_handle(void **new_handle, apr_pool_t *p, + int child_num, int thread_num) +{ + sb_handle *sbh; + + sbh = (sb_handle *)apr_palloc(p, sizeof *sbh); + *new_handle = sbh; + sbh->child_num = child_num; + sbh->thread_num = thread_num; +} + +AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, int thread_num, + int status, request_rec *r) { int old_status, i; worker_score *ws; @@ -292,9 +343,9 @@ AP_DECLARE(int) ap_update_child_status(int child_num, int thread_num, int status if (status == SERVER_READY && old_status == SERVER_STARTING) { - ws->thread_num = child_num * HARD_SERVER_LIMIT + thread_num; + ws->thread_num = child_num * server_limit + thread_num; if (ps->generation != ap_my_generation) { - for (i = 0; i < HARD_THREAD_LIMIT; i++) { + for (i = 0; i < thread_limit; i++) { ap_scoreboard_image->servers[child_num][i].vhostrec = NULL; } ps->generation = ap_my_generation; @@ -337,6 +388,14 @@ AP_DECLARE(int) ap_update_child_status(int child_num, int thread_num, int status return old_status; } +AP_DECLARE(int)ap_update_child_status(void *sbh, int status, request_rec *r) +{ + sb_handle *sb = sbh; + + return ap_update_child_status_from_indexes(sb->child_num, sb->thread_num, + status, r); +} + void ap_time_process_request(int child_num, int thread_num, int status) { worker_score *ws; @@ -357,8 +416,8 @@ void ap_time_process_request(int child_num, int thread_num, int status) AP_DECLARE(worker_score *) ap_get_servers_scoreboard(int x, int y) { - if (((x < 0) || (HARD_SERVER_LIMIT < x)) || - ((y < 0) || (HARD_THREAD_LIMIT < y))) { + if (((x < 0) || (server_limit < x)) || + ((y < 0) || (thread_limit < y))) { return(NULL); /* Out of range */ } return(&ap_scoreboard_image->servers[x][y]); @@ -366,7 +425,7 @@ AP_DECLARE(worker_score *) ap_get_servers_scoreboard(int x, int y) AP_DECLARE(process_score *) ap_get_parent_scoreboard(int x) { - if ((x < 0) || (HARD_SERVER_LIMIT < x)) { + if ((x < 0) || (server_limit < x)) { return(NULL); /* Out of range */ } return(&ap_scoreboard_image->parent[x]); |