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
* 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;
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.
/* 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) {
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
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);
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));
}
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) {
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));
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) {
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);
}
}
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;
}
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) {
/*
- * 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
{
int i, j;
int idle_thread_count;
- thread_score *ss;
time_t now = 0;
int free_length;
int free_slots[MAX_SPAWN_RATE];
/* 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
*/
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 {
- idle_spawn_rate = 1;
+ } else {
+ spawn_rate = 1;
}
}
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) {
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 = '!';
/* 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
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));
}
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;
"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 }
*
*/
-#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;
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 */
#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;
-
-/*****************************************************************
- *
- * 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...
- */
+static int maintain_connection_status = 1;
void reinit_scoreboard(ap_context_t *p)
{
ap_scoreboard_image = NULL;
}
-API_EXPORT(void) reopen_scoreboard(ap_context_t *p)
-{
-}
-
-API_EXPORT(void) ap_sync_scoreboard_image(void)
-{
-}
-
API_EXPORT(int) ap_exists_scoreboard_image(void)
{
return (ap_scoreboard_image ? 1 : 0);
}
-static ap_inline void put_scoreboard_info(int child_num, int thread_num,
- thread_score *new_score_rec)
-{
- /* XXX - needs to be fixed to account for threads */
-}
-void update_scoreboard_global(void)
+void ap_update_connection_status(long conn_id, const char *key,
+ const char *value)
{
+ 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;
}
-void increment_counts(int child_num, int thread_num, request_rec *r)
+void ap_reset_connection_status(long conn_id)
{
- long int bs = 0;
- thread_score *ss;
-
- ss = &ap_scoreboard_image->servers[child_num][thread_num];
-
- if (r->sent_bodyct)
- ap_bgetopt(r->connection->client, BO_BYTECT, &bs);
-
-#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;
-
- put_scoreboard_info(child_num, thread_num, ss);
+ if (maintain_connection_status) {
+ ap_mpmt_beos_force_reset_connection_status(conn_id);
+ }
+}
+void ap_mpmt_beos_set_maintain_connection_status(int flag) {
+ maintain_connection_status = flag;
+ return;
}
-API_EXPORT(int) find_child_by_pid(int pid)
+void ap_mpmt_beos_force_reset_connection_status(long conn_id)
{
int i;
- int max_daemons_limit = ap_get_max_daemons();
- for (i = 0; i < max_daemons_limit; ++i)
- if (ap_scoreboard_image->parent[i].pid == pid)
- return i;
-
- return -1;
+ for (i = 0; i < STATUSES_PER_CONNECTION; i++) {
+ ap_scoreboard_image->table[conn_id][i].key[0] = '\0';
+ }
}
-int ap_update_child_status(int child_num, int thread_num, int status, request_rec *r)
+const char *ap_get_connection_status(long conn_id, const char *key)
{
- 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;
+ 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)) {
+ return ss->value;
+ }
}
- 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;
+ return NULL;
}
-void ap_time_process_request(int child_num, int thread_num, int status)
+ap_array_header_t *ap_get_connections(ap_context_t *p)
{
- 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;
+ int i;
+ ap_array_header_t *connection_list;
+ long *array_slot;
+
+ 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;
}
-
*
*/
-#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 */