dreid 99/11/02 09:29:32
Modified: src/modules/mpm/mpmt_beos mpmt_beos.c mpmt_beos.h scoreboard.c scoreboard.h Log: Add support for connection_info to BeOS. This follows the stuff Manoj has added to dexter. Also take the opportunity to clean-up some of the code. Revision Changes Path 1.8 +75 -144 apache-2.0/src/modules/mpm/mpmt_beos/mpmt_beos.c Index: mpmt_beos.c =================================================================== RCS file: /home/cvs/apache-2.0/src/modules/mpm/mpmt_beos/mpmt_beos.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- mpmt_beos.c 1999/11/02 12:26:41 1.7 +++ mpmt_beos.c 1999/11/02 17:29:18 1.8 @@ -104,6 +104,15 @@ ap_context_t *tpool; /* "pthread" would be confusing */ } proc_info; +#define SERVER_DEAD 0 +#define SERVER_DYING 1 +#define SERVER_ALIVE 2 + +static struct { + pid_t pid; + unsigned char status; +} child_table[HARD_SERVER_LIMIT]; + #if 0 #define SAFE_ACCEPT(stmt) do {if (ap_listeners->next != NULL) {stmt;}} while (0) #else @@ -115,7 +124,7 @@ * to deal with MaxClients changes across SIGWINCH restarts. We use this * value to optimize routines that have to scan the entire scoreboard. */ -static int max_daemons_limit = -1; +int max_daemons_limit = -1; static char ap_coredump_dir[MAX_STRING_LEN]; port_id port_of_death; @@ -307,8 +316,6 @@ other_child_rec *ocr, *nocr; #endif - ap_sync_scoreboard_image(); - for (tries = terminate ? 4 : 1; tries <= 9; ++tries) { /* don't want to hold up progress any more than * necessary, but we need to allow children a few moments to exit. @@ -322,15 +329,16 @@ /* now see who is done */ not_dead_yet = 0; for (i = 0; i < max_daemons_limit; ++i) { - int pid = ap_scoreboard_image->parent[i].pid; + int pid; + if (child_table[i].status == SERVER_DEAD) + continue; - if (pid == my_pid || pid == 0) - continue; + pid = child_table[i].pid; waitret = waitpid(pid, &status, WNOHANG); if (waitret == pid || waitret == -1) { - ap_scoreboard_image->parent[i].pid = 0; - continue; + child_table[i].status = SERVER_DEAD; + continue; } ++not_dead_yet; switch (tries) { @@ -460,7 +468,6 @@ static int volatile shutdown_pending; static int volatile restart_pending; static int volatile is_graceful; -ap_generation_t volatile ap_my_generation; /* * ap_start_shutdown() and ap_start_restart(), below, are a first stab at @@ -659,8 +666,6 @@ return; } - (void) ap_update_child_status(my_child_num, my_thread_num, - SERVER_BUSY_READ, (request_rec *) NULL); conn_io = ap_bcreate(p, B_RDWR); ap_bpush_iol(conn_io, iol); @@ -703,8 +708,6 @@ workers_may_exit |= (ap_max_requests_per_child != 0) && (requests_this_child <= 0); if (workers_may_exit) break; - (void) ap_update_child_status(process_slot, thread_slot, SERVER_READY, - (request_rec *) NULL); SAFE_ACCEPT(intra_mutex_on(0)); if (workers_may_exit) { SAFE_ACCEPT(intra_mutex_off(0)); @@ -766,8 +769,6 @@ } ap_destroy_pool(tpool); - ap_update_child_status(process_slot, thread_slot, SERVER_DEAD, - (request_rec *) NULL); be_mutex_lock(&worker_thread_count_mutex); worker_thread_count--; if (worker_thread_count == 0) { @@ -798,8 +799,6 @@ ap_create_context(&pchild, pconf); /*stuff to do before we switch id's, so we have permissions.*/ - reopen_scoreboard(pchild); - SAFE_ACCEPT(intra_mutex_init(pchild, 1)); SAFE_ACCEPT(accept_mutex_child_init(pchild)); @@ -844,8 +843,6 @@ ap_create_context(&my_info->tpool, pchild); /* We are creating threads right now */ - (void) ap_update_child_status(my_child_num, i, SERVER_STARTING, - (request_rec *) NULL); if ((thread = spawn_thread(worker_thread, "httpd_worker_thread", B_NORMAL_PRIORITY, my_info)) < B_NO_ERROR) { @@ -885,7 +882,8 @@ if (one_process) { set_signals(); - ap_scoreboard_image->parent[slot].pid = getpid(); + child_table[slot].pid = getpid(); + child_table[slot].status = SERVER_ALIVE; //child_main(slot); } @@ -903,14 +901,8 @@ } resume_thread(tid); -/* if (!pid) { - RAISE_SIGSTOP(MAKE_CHILD); - signal(SIGTERM, just_die); - child_main(slot); - return 0; - }*/ - /* else */ - ap_scoreboard_image->parent[slot].pid = tid; + child_table[slot].pid = getpid(); + child_table[slot].status = SERVER_ALIVE; return 0; } @@ -920,7 +912,7 @@ int i; for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { - if (ap_scoreboard_image->parent[i].pid != 0) { + if (child_table[i].status != SERVER_DEAD) { continue; } if (make_child(server_conf, i, 0) < 0) { @@ -932,12 +924,12 @@ /* - * idle_spawn_rate is the number of children that will be spawned on the + * spawn_rate is the number of children that will be spawned on the * next maintenance cycle if there aren't enough idle servers. It is * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by * without the need to spawn. */ -static int idle_spawn_rate = 1; +static int spawn_rate = 1; #ifndef MAX_SPAWN_RATE #define MAX_SPAWN_RATE (32) #endif @@ -947,7 +939,6 @@ { int i, j; int idle_thread_count; - thread_score *ss; time_t now = 0; int free_length; int free_slots[MAX_SPAWN_RATE]; @@ -957,91 +948,27 @@ /* initialize the free_list */ free_length = 0; - idle_thread_count = 0; - last_non_dead = -1; - total_non_dead = 0; - ap_check_signals(); - - ap_sync_scoreboard_image(); + for (i = 0; i < ap_daemons_limit; ++i) { - /* Initialization to satisfy the compiler. It doesn't know - * that ap_threads_per_child is always > 0 */ - int status = SERVER_DEAD; - int any_dying_threads = 0; - int all_dead_threads = 1; - int idle_thread_addition = 0; - - if (i >= max_daemons_limit && free_length == idle_spawn_rate) - break; - for (j = 0; j < ap_threads_per_child; j++) { - ss = &ap_scoreboard_image->servers[i][j]; - status = ss->status; - - any_dying_threads = any_dying_threads || (status == SERVER_DEAD) - || (status == SERVER_GRACEFUL); - all_dead_threads = all_dead_threads && (status == SERVER_DEAD); - - /* We consider a starting server as idle because we started it - * at least a cycle ago, and if it still hasn't finished starting - * then we're just going to swamp things worse by forking more. - * So we hopefully won't need to fork more if we count it. - * This depends on the ordering of SERVER_READY and SERVER_STARTING. - */ - if (status <= SERVER_READY) { - ++idle_thread_addition; - } - } - if (all_dead_threads && free_length < idle_spawn_rate) { - free_slots[free_length] = i; - ++free_length; - } - if (!all_dead_threads) { + if (child_table[i].status == SERVER_DEAD) { + if (free_length < spawn_rate) { + free_slots[free_length] = i; + ++free_length; + } + } + else { last_non_dead = i; - } - if (!any_dying_threads) { - ++total_non_dead; - idle_thread_count += idle_thread_addition; } + + if (i >= max_daemons_limit && free_length >= spawn_rate) { + break; + } } max_daemons_limit = last_non_dead + 1; - if (idle_thread_count > max_spare_threads) { - /* Kill off one child */ - char char_of_death = '!'; - if (write_port(port_of_death, 99, &char_of_death, 1) != B_OK) { - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, - "write pipe_of_death"); - } - idle_spawn_rate = 1; - } - else if (idle_thread_count < min_spare_threads) { - /* terminate the free list */ - if (free_length == 0) { - /* only report this condition once */ - static int reported = 0; - - if (!reported) { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, errno, server_conf, - "server reached MaxClients setting, consider" - " raising the MaxClients setting"); - reported = 1; - } - idle_spawn_rate = 1; - } - else { - /* ZZZZ */ - - if (idle_spawn_rate >= 8) { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, errno, server_conf, - "server seems busy, (you may need " - "to increase StartServers, ThreadsPerChild " - "or Min/MaxSparetThreads), " - "spawning %d children, there are around %d idle " - "threads, and %d total children", idle_spawn_rate, - idle_thread_count, total_non_dead); - } - for (i = 0; i < free_length; ++i) { + if (free_length > 0) { + for (i = 0; i < free_length; ++i) { make_child(server_conf, free_slots[i], now); } /* the next time around we want to spawn twice as many if this @@ -1049,15 +976,12 @@ */ if (hold_off_on_exponential_spawning) { --hold_off_on_exponential_spawning; + } else if (spawn_rate < MAX_SPAWN_RATE) { + spawn_rate *= 2; } - else if (idle_spawn_rate < MAX_SPAWN_RATE) { - idle_spawn_rate *= 2; - } - } + } else { + spawn_rate = 1; } - else { - idle_spawn_rate = 1; - } } static void server_main_loop(int remaining_children_to_start) @@ -1073,10 +997,20 @@ if (pid >= 0) { process_child_status(pid, status); /* non-fatal death... note that it's gone in the scoreboard. */ - child_slot = find_child_by_pid(pid); + child_slot = -1; + for (i = 0; i < max_daemons_limit; ++i) { + if (child_table[i].pid == pid) { + int j; + + child_slot = i; + for (j = 0; j < HARD_THREAD_LIMIT; j++) { + ap_mpmt_beos_force_reset_connection_status(i * HARD_THREAD_LIMIT + j); + } + break; + } + } 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); + child_table[child_slot].status = SERVER_DEAD; if (remaining_children_to_start && child_slot < ap_daemons_limit) { @@ -1217,14 +1151,6 @@ return 1; } - /* advance to the next generation */ - /* XXX: we really need to make sure this new generation number isn't in - * use by any of the children. - */ - ++ap_my_generation; - ap_scoreboard_image->global.running_generation = ap_my_generation; - update_scoreboard_global(); - if (is_graceful) { int i, j; char char_of_death = '!'; @@ -1234,25 +1160,16 @@ /* give the children the signal to die */ for (i = 0; i < ap_daemons_limit;) { - if (write_port(port_of_death, 99, &char_of_death, 1) != B_OK) { - if (errno == EINTR) continue; - ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, - "write pipe_of_death"); + if(child_table[i].status != SERVER_DEAD) { + if (write_port(port_of_death, 99, &char_of_death, 1) != B_OK) { + if (errno == EINTR) continue; + ap_log_error(APLOG_MARK, APLOG_WARNING, errno, server_conf, + "write port_of_death"); + } } i++; } - /* This is mostly for debugging... so that we know what is still - * gracefully dealing with existing request. - */ - - for (i = 0; i < ap_daemons_limit; ++i) { - for (j = 0; j < ap_threads_per_child; j++) { - if (ap_scoreboard_image->servers[i][j].status != SERVER_DEAD) { - ap_scoreboard_image->servers[i][j].status = SERVER_GRACEFUL; - } - } - } } else { /* Kill 'em all. Since the child acts the same on the parents SIGTERM @@ -1301,7 +1218,7 @@ ap_pid_fname = DEFAULT_PIDLOG; ap_scoreboard_fname = DEFAULT_SCOREBOARD; ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; - ap_extended_status = 0; + ap_mpmt_beos_set_maintain_connection_status(1); ap_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); } @@ -1437,6 +1354,18 @@ return NULL; } +static const char *set_maintain_connection_status(cmd_parms *cmd, + core_dir_config *d, int arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_mpmt_beos_set_maintain_connection_status(arg != 0); + return NULL; +} + static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, char *arg) { struct stat finfo; @@ -1508,6 +1437,8 @@ "Number of threads each child creates" }, { "MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF, TAKE1, "Maximum number of requests a particular child serves before dying." }, +{ "ConnectionStatus", set_maintain_connection_status, NULL, RSRC_CONF, FLAG, + "Whether or not to maintain status information on current connections"}, { "CoreDumpDirectory", set_coredumpdir, NULL, RSRC_CONF, TAKE1, "The location of the directory Apache changes to before dumping core" }, { NULL } 1.2 +4 -3 apache-2.0/src/modules/mpm/mpmt_beos/mpmt_beos.h Index: mpmt_beos.h =================================================================== RCS file: /home/cvs/apache-2.0/src/modules/mpm/mpmt_beos/mpmt_beos.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- mpmt_beos.h 1999/10/08 19:02:34 1.1 +++ mpmt_beos.h 1999/11/02 17:29:20 1.2 @@ -55,8 +55,8 @@ * */ -#ifndef APACHE_MPM_MPMT_PTHREAD_H -#define APACHE_MPM_MPMT_PTHREAD_H +#ifndef APACHE_MPM_MPMT_BEOS_H +#define APACHE_MPM_MPMT_BEOS_H extern int ap_threads_per_child; extern int ap_max_requests_per_child; @@ -64,5 +64,6 @@ extern void clean_child_exit(int); extern int ap_extended_status; extern void clean_child_exit(int); +extern int max_daemons_limit; -#endif /* APACHE_MPM_MPMT_PTHREAD_H */ +#endif /* APACHE_MPM_MPMT_BEOS_H */ 1.3 +107 -135 apache-2.0/src/modules/mpm/mpmt_beos/scoreboard.c Index: scoreboard.c =================================================================== RCS file: /home/cvs/apache-2.0/src/modules/mpm/mpmt_beos/scoreboard.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- scoreboard.c 1999/10/13 18:16:40 1.2 +++ scoreboard.c 1999/11/02 17:29:24 1.3 @@ -3,24 +3,16 @@ #include "http_main.h" #include "http_core.h" #include "http_config.h" +#include "mpm_status.h" #include "beosd.h" #include "http_conf_globals.h" #include "mpmt_beos.h" #include "scoreboard.h" scoreboard *ap_scoreboard_image = NULL; -//static char *ap_server_argv0=NULL; extern ap_context_t * pconf; +static int maintain_connection_status = 1; -/***************************************************************** - * - * Dealing with the scoreboard... a lot of these variables are global - * only to avoid getting clobbered by the longjmp() that happens when - * a hard timeout expires... - * - * We begin with routines which deal with the file itself... - */ - void reinit_scoreboard(ap_context_t *p) { ap_assert(!ap_scoreboard_image); @@ -38,159 +30,139 @@ ap_scoreboard_image = NULL; } -API_EXPORT(void) reopen_scoreboard(ap_context_t *p) +API_EXPORT(int) ap_exists_scoreboard_image(void) { + return (ap_scoreboard_image ? 1 : 0); } -API_EXPORT(void) ap_sync_scoreboard_image(void) -{ -} -API_EXPORT(int) ap_exists_scoreboard_image(void) +void ap_update_connection_status(long conn_id, const char *key, + const char *value) { - return (ap_scoreboard_image ? 1 : 0); + int i = 0; + status_table_entry *ss; + + if (!maintain_connection_status) return; + while (i < STATUSES_PER_CONNECTION) { + ss = &(ap_scoreboard_image->table[conn_id][i]); + if (ss->key[0] == '\0') { + break; + } + if (0 == strcmp(ss->key, key)) { + ap_cpystrn(ss->value, value, VALUE_LENGTH); + return; + } + i++; + } + if (i >= STATUSES_PER_CONNECTION) { + return; + } + ap_cpystrn(ss->key, key, KEY_LENGTH); + ap_cpystrn(ss->value, value, VALUE_LENGTH); + return; } -static ap_inline void put_scoreboard_info(int child_num, int thread_num, - thread_score *new_score_rec) +void ap_reset_connection_status(long conn_id) { - /* XXX - needs to be fixed to account for threads */ + if (maintain_connection_status) { + ap_mpmt_beos_force_reset_connection_status(conn_id); + } } -void update_scoreboard_global(void) -{ +void ap_mpmt_beos_set_maintain_connection_status(int flag) { + maintain_connection_status = flag; + return; } -void increment_counts(int child_num, int thread_num, request_rec *r) +void ap_mpmt_beos_force_reset_connection_status(long conn_id) { - long int bs = 0; - thread_score *ss; - - ss = &ap_scoreboard_image->servers[child_num][thread_num]; + int i; - if (r->sent_bodyct) - ap_bgetopt(r->connection->client, BO_BYTECT, &bs); + for (i = 0; i < STATUSES_PER_CONNECTION; i++) { + ap_scoreboard_image->table[conn_id][i].key[0] = '\0'; + } +} -#ifndef NO_TIMES - times(&ss->times); -#endif - ss->access_count++; - ss->my_access_count++; - ss->conn_count++; - ss->bytes_served += (unsigned long) bs; - ss->my_bytes_served += (unsigned long) bs; - ss->conn_bytes += (unsigned long) bs; +const char *ap_get_connection_status(long conn_id, const char *key) +{ + int i = 0; + status_table_entry *ss; - put_scoreboard_info(child_num, thread_num, ss); + if (!maintain_connection_status) return ""; + while (i < STATUSES_PER_CONNECTION) { + ss = &(ap_scoreboard_image->table[conn_id][i]); + if (ss->key[0] == '\0') { + break; + } + if (0 == strcmp(ss->key, key)) { + return ss->value; + } + } + return NULL; } -API_EXPORT(int) find_child_by_pid(int pid) +ap_array_header_t *ap_get_connections(ap_context_t *p) { int i; - int max_daemons_limit = ap_get_max_daemons(); + ap_array_header_t *connection_list; + long *array_slot; - for (i = 0; i < max_daemons_limit; ++i) - if (ap_scoreboard_image->parent[i].pid == pid) - return i; - - return -1; -} - -int ap_update_child_status(int child_num, int thread_num, int status, request_rec *r) -{ - int old_status; - thread_score *ss; - parent_score *ps; - - if (child_num < 0) - return -1; - - ss = &ap_scoreboard_image->servers[child_num][thread_num]; - old_status = ss->status; - ss->status = status; - - ps = &ap_scoreboard_image->parent[child_num]; - - if ((status == SERVER_READY || status == SERVER_ACCEPTING) - && old_status == SERVER_STARTING) { - ss->tid = find_thread(NULL); - ps->worker_threads = ap_threads_per_child; - } - - if (ap_extended_status) { - if (status == SERVER_READY || status == SERVER_DEAD) { - /* - * Reset individual counters - */ - if (status == SERVER_DEAD) { - ss->my_access_count = 0L; - ss->my_bytes_served = 0L; - } - ss->conn_count = (unsigned short) 0; - ss->conn_bytes = (unsigned long) 0; - } - if (r) { - conn_rec *c = r->connection; - ap_cpystrn(ss->client, ap_get_remote_host(c, r->per_dir_config, - REMOTE_NOLOOKUP), sizeof(ss->client)); - if (r->the_request == NULL) { - ap_cpystrn(ss->request, "NULL", sizeof(ss->request)); - } else if (r->parsed_uri.password == NULL) { - ap_cpystrn(ss->request, r->the_request, sizeof(ss->request)); - } else { - /* Don't reveal the password in the server-status view */ - ap_cpystrn(ss->request, ap_pstrcat(r->pool, r->method, " ", - ap_unparse_uri_components(r->pool, &r->parsed_uri, UNP_OMITPASSWORD), - r->assbackwards ? NULL : " ", r->protocol, NULL), - sizeof(ss->request)); - } - ss->vhostrec = r->server; - } - } - - put_scoreboard_info(child_num, thread_num, ss); - return old_status; -} - -void ap_time_process_request(int child_num, int thread_num, int status) -{ - thread_score *ss; - - if (child_num < 0) - return; - - ss = &ap_scoreboard_image->servers[child_num][thread_num]; - - if (status == START_PREQUEST) { - /*ss->start_time = GetCurrentTime(); ZZZ return time in uS since the - epoch. Some platforms do not support gettimeofday. Create a routine - to get the current time is some useful units. */ - if (gettimeofday(&ss->start_time, (struct timezone *) 0) < 0) { - ss->start_time.tv_sec = ss->start_time.tv_usec = 0L; - } - } - else if (status == STOP_PREQUEST) { - /*ss->stop_time = GetCurrentTime(); - ZZZ return time in uS since the epoch */ - - if (gettimeofday(&ss->stop_time, (struct timezone *) 0) < 0) { - ss->start_time.tv_sec = ss->start_time.tv_usec = 0L; + connection_list = ap_make_array(p, 0, sizeof(long)); + for (i = 0; i < max_daemons_limit*HARD_THREAD_LIMIT; i++) { + if (ap_scoreboard_image->table[i][0].key[0] != '\0') { + array_slot = ap_push_array(connection_list); + *array_slot = i; } } - put_scoreboard_info(child_num, thread_num, ss); + return connection_list; } -/* Stub functions until this MPM supports the connection status API */ - -API_EXPORT(void) ap_update_connection_status(long conn_id, const char *key, \ - const char *value) +ap_array_header_t *ap_get_connection_keys(ap_context_t *p, long conn_id) { - /* NOP */ + int i = 0; + status_table_entry *ss; + ap_array_header_t *key_list; + char **array_slot; + + key_list = ap_make_array(p, 0, KEY_LENGTH * sizeof(char)); + while (i < STATUSES_PER_CONNECTION) { + ss = &(ap_scoreboard_image->table[conn_id][i]); + if (ss->key[0] == '\0') { + break; + } + array_slot = ap_push_array(key_list); + *array_slot = ap_pstrdup(p, ss->key); + i++; + } + return key_list; } -API_EXPORT(void) ap_reset_connection_status(long conn_id) +ap_array_header_t *ap_get_status_table(ap_context_t *p) { - /* NOP */ -} + int i, j; + ap_array_header_t *server_status; + ap_status_table_row_t *array_slot; + status_table_entry *ss; + + server_status = ap_make_array(p, 0, sizeof(ap_status_table_row_t)); + for (i = 0; i < max_daemons_limit*HARD_THREAD_LIMIT; i++) { + if (ap_scoreboard_image->table[i][0].key[0] == '\0') + continue; + array_slot = ap_push_array(server_status); + array_slot->data = ap_make_table(p, 0); + array_slot->conn_id = i; + + for (j = 0; j < STATUSES_PER_CONNECTION; j++) { + ss = &(ap_scoreboard_image->table[i][j]); + if (ss->key[0] != '\0') { + ap_table_add(array_slot->data, ss->key, ss->value); + } + else { + break; + } + } + } + return server_status; +} 1.2 +20 -151 apache-2.0/src/modules/mpm/mpmt_beos/scoreboard.h Index: scoreboard.h =================================================================== RCS file: /home/cvs/apache-2.0/src/modules/mpm/mpmt_beos/scoreboard.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- scoreboard.h 1999/10/08 19:02:36 1.1 +++ scoreboard.h 1999/11/02 17:29:26 1.2 @@ -55,179 +55,48 @@ * */ -#ifndef APACHE_SCOREBOARD_H -#define APACHE_SCOREBOARD_H +#ifndef MPMT_BEOS_SCOREBOARD_H +#define MPMT_BEOS_SCOREBOARD_H #ifdef __cplusplus extern "C" { #endif -#ifndef WIN32 -#ifdef TPF -#include <time.h> -#else -#include <sys/times.h> -#endif /* TPF */ -#endif +#include <sys/times.h> #include "mpm_default.h" /* For HARD_.*_LIMIT */ -/* Scoreboard info on a process is, for now, kept very brief --- - * just status value and pid (the latter so that the caretaker process - * can properly update the scoreboard when a process dies). We may want - * to eventually add a separate set of long_score structures which would - * give, for each process, the number of requests serviced, and info on - * the current, or most recent, request. - * - * Status values: - */ - -#define SERVER_DEAD 0 -#define SERVER_STARTING 1 /* Server Starting up */ -#define SERVER_READY 2 /* Waiting for connection (or accept() lock) */ -#define SERVER_BUSY_READ 3 /* Reading a client request */ -#define SERVER_BUSY_WRITE 4 /* Processing a client request */ -#define SERVER_BUSY_KEEPALIVE 5 /* Waiting for more requests via keepalive */ -#define SERVER_BUSY_LOG 6 /* Logging the request */ -#define SERVER_BUSY_DNS 7 /* Looking up a hostname */ -#define SERVER_GRACEFUL 8 /* server is gracefully finishing request */ -#define SERVER_ACCEPTING 9 /* thread is accepting connections */ -#define SERVER_QUEUEING 10 /* thread is putting connection on the queue */ -#define SERVER_NUM_STATUS 11 /* number of status settings */ - -/* A "virtual time" is simply a counter that indicates that a child is - * making progress. The parent checks up on each child, and when they have - * made progress it resets the last_rtime element. But when the child hasn't - * made progress in a time that's roughly timeout_len seconds long, it is - * sent a SIGALRM. - * - * vtime is an optimization that is used only when the scoreboard is in - * shared memory (it's not easy/feasible to do it in a scoreboard file). - * The essential observation is that timeouts rarely occur, the vast majority - * of hits finish before any timeout happens. So it really sucks to have to - * ask the operating system to set up and destroy alarms many times during - * a request. - */ -typedef unsigned vtime_t; - -/* Type used for generation indicies. Startup and every restart cause a - * new generation of children to be spawned. Children within the same - * generation share the same configuration information -- pointers to stuff - * created at config time in the parent are valid across children. For - * example, the vhostrec pointer in the scoreboard below is valid in all - * children of the same generation. - * - * The safe way to access the vhost pointer is like this: - * - * short_score *ss = pointer to whichver slot is interesting; - * parent_score *ps = pointer to whichver slot is interesting; - * server_rec *vh = ss->vhostrec; - * - * if (ps->generation != ap_my_generation) { - * vh = NULL; - * } - * - * then if vh is not NULL it's valid in this child. - * - * This avoids various race conditions around restarts. - */ -typedef int ap_generation_t; - -/* stuff which is thread specific */ -typedef struct { -#ifdef OPTIMIZE_TIMEOUTS - vtime_t cur_vtime; /* the child's current vtime */ - unsigned short timeout_len; /* length of the timeout */ -#endif - thread_id tid; - unsigned char status; - unsigned long access_count; - unsigned long bytes_served; - unsigned long my_access_count; - unsigned long my_bytes_served; - unsigned long conn_bytes; - unsigned short conn_count; -#if defined(NO_GETTIMEOFDAY) - clock_t start_time; - clock_t stop_time; -#else - struct timeval start_time; - struct timeval stop_time; -#endif -#ifndef NO_TIMES - struct tms times; -#endif -#ifndef OPTIMIZE_TIMEOUTS - time_t last_used; -#endif - char client[32]; /* Keep 'em small... */ - char request[64]; /* We just want an idea... */ - server_rec *vhostrec; /* What virtual host is being accessed? */ - /* SEE ABOVE FOR SAFE USAGE! */ -} thread_score; - -typedef struct { - ap_generation_t running_generation; /* the generation of children which - * should still be serving requests. */ -} global_score; - -/* stuff which the parent generally writes and the children rarely read */ -typedef struct { - pid_t pid; - ap_generation_t generation; /* generation of this child */ - int worker_threads; -#ifdef OPTIMIZE_TIMEOUTS - time_t last_rtime; /* time(0) of the last change */ - vtime_t last_vtime; /* the last vtime the parent has seen */ -#endif -} parent_score; - -typedef struct { - thread_score servers[HARD_SERVER_LIMIT][HARD_THREAD_LIMIT]; - parent_score parent[HARD_SERVER_LIMIT]; - global_score global; -} scoreboard; - -#define SCOREBOARD_SIZE sizeof(scoreboard) -#ifdef TPF -#define SCOREBOARD_NAME "SCOREBRD" -#define SCOREBOARD_FRAMES SCOREBOARD_SIZE/4095 + 1 -#endif - API_EXPORT(int) ap_exists_scoreboard_image(void); void reinit_scoareboard(ap_context_t *p); void cleanup_scoreboard(void); -API_EXPORT(void) ap_sync_scoreboard_image(void); - -#if defined(USE_OS2_SCOREBOARD) -caddr_t create_shared_heap(const char *name, size_t size); -caddr_t get_shared_heap(const char *Name); -#elif defined(USE_POSIX_SCOREBOARD) -static void cleanup_shared_mem(void *d); -#else +void ap_mpmt_beos_set_maintain_connection_status(int flag); +void ap_mpmt_beos_force_reset_connection_status(long conn_id); void reinit_scoreboard(ap_context_t *p); -#endif - -API_EXPORT(void) reopen_scoreboard(ap_context_t *p); - -ap_inline void ap_sync_scoreboard_image(void); -void increment_counts(int child_num, int thread_num, request_rec *r); void update_scoreboard_global(void); API_EXPORT(int) find_child_by_pid(int pid); int ap_update_child_status(int child_num, int thread_num, int status, request_rec *r); void ap_time_process_request(int child_num, int thread_num, int status); +/* Add support for connection table functions */ +#define KEY_LENGTH 16 +#define VALUE_LENGTH 64 -API_VAR_EXPORT extern scoreboard *ap_scoreboard_image; +typedef struct { + char key[KEY_LENGTH]; + char value[VALUE_LENGTH]; +} status_table_entry; -API_VAR_EXPORT extern ap_generation_t volatile ap_my_generation; +#define STATUSES_PER_CONNECTION 10 -/* for time_process_request() in http_main.c */ -#define START_PREQUEST 1 -#define STOP_PREQUEST 2 +typedef struct { + status_table_entry + table[HARD_SERVER_LIMIT*HARD_THREAD_LIMIT][STATUSES_PER_CONNECTION]; +} scoreboard; + +#define SCOREBOARD_SIZE sizeof(scoreboard) #ifdef __cplusplus } #endif -#endif /* !APACHE_SCOREBOARD_H */ +#endif /* !MPMT_BEOS_SCOREBOARD_H */