Changes with Apache 2.0.18-dev
+ *) Make first phase changes to the scoreboard data structures in
+ preparation for the rewriting of the scoreboard per my posted
+ design notes. [Paul J. Reder]
+
*) Fix httpd's definition of LTFLAGS to be consistent with that of apr
and apr-util, allow it to be overridden by the configure command-line
(default="--silent") and introduce LT_LDFLAGS to replace what we were
*
* 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;
+ * worker_score *ss = pointer to whichver slot is interesting;
+ * process_score *ps = pointer to whichver slot is interesting;
* server_rec *vh = ss->vhostrec;
*
* if (ps->generation != ap_my_generation) {
#define SB_IDLE_DIE 1 /* The server is idle and the child is superfluous. */
/* The child should check for this and exit gracefully. */
-/* stuff which is thread/process specific */
-typedef struct {
+/* stuff which is worker specific */
+/***********************WARNING***************************************/
+/* These are things that are used by mod_status. Do not put anything */
+/* in here that you cannot live without. This structure will not */
+/* be available if mod_status is not loaded. */
+/*********************************************************************/
+typedef struct worker_score worker_score;
+
+struct worker_score {
int thread_num;
#if APR_HAS_THREADS
apr_os_thread_t tid;
unsigned long my_bytes_served;
unsigned long conn_bytes;
unsigned short conn_count;
- unsigned short life_status; /* Either SB_WORKING or SB_IDLE_DIE */
apr_time_t start_time;
apr_time_t stop_time;
#ifdef HAVE_TIMES
char request[64]; /* We just want an idea... */
server_rec *vhostrec; /* What virtual host is being accessed? */
/* SEE ABOVE FOR SAFE USAGE! */
-} short_score;
+ worker_score *next;
+};
typedef struct {
ap_scoreboard_e sb_type;
} global_score;
/* stuff which the parent generally writes and the children rarely read */
-typedef struct {
+typedef struct process_score process_score;
+struct process_score{
pid_t pid;
ap_generation_t generation; /* generation of this child */
+ ap_scoreboard_e sb_type;
+ unsigned short process_status; /* Either SB_WORKING or SB_IDLE_DIE */
int worker_threads;
-} parent_score;
+ worker_score *worker_head;
+ process_score *next;
+};
typedef struct {
- short_score servers[HARD_SERVER_LIMIT][HARD_THREAD_LIMIT];
- parent_score parent[HARD_SERVER_LIMIT];
+ worker_score servers[HARD_SERVER_LIMIT][HARD_THREAD_LIMIT];
+ process_score parent[HARD_SERVER_LIMIT];
global_score global;
} scoreboard;
char value[VALUE_LENGTH];
} status_table_entry;
-#define STATUSES_PER_CONNECTION 10
-
-typedef struct {
- status_table_entry
- table[HARD_SERVER_LIMIT*HARD_THREAD_LIMIT][STATUSES_PER_CONNECTION];
-} new_scoreboard;
-
#define SCOREBOARD_SIZE sizeof(scoreboard)
#define NEW_SCOREBOARD_SIZE sizeof(new_scoreboard)
#ifdef TPF
#endif
int short_report = 0;
int no_table_report = 0;
- short_score score_record;
- parent_score ps_record;
+ worker_score ws_record;
+ process_score ps_record;
char stat_buffer[HARD_SERVER_LIMIT * HARD_THREAD_LIMIT];
pid_t pid_buffer[HARD_SERVER_LIMIT * HARD_THREAD_LIMIT];
clock_t tu, ts, tcu, tcs;
for (j = 0; j < HARD_THREAD_LIMIT; ++j) {
int indx = (i * HARD_THREAD_LIMIT) + j;
- score_record = ap_scoreboard_image->servers[i][j];
+ ws_record = ap_scoreboard_image->servers[i][j];
ps_record = ap_scoreboard_image->parent[i];
- res = score_record.status;
+ res = ws_record.status;
stat_buffer[indx] = status_flags[res];
pid_buffer[indx] = ps_record.pid;
if (res == SERVER_READY)
else if (res != SERVER_DEAD)
busy++;
if (ap_extended_status) {
- lres = score_record.access_count;
- bytes = score_record.bytes_served;
+ lres = ws_record.access_count;
+ bytes = ws_record.bytes_served;
if (lres != 0 || (res != SERVER_READY && res != SERVER_DEAD)) {
#ifdef HAVE_TIMES
- tu += score_record.times.tms_utime;
- ts += score_record.times.tms_stime;
- tcu += score_record.times.tms_cutime;
- tcs += score_record.times.tms_cstime;
+ tu += ws_record.times.tms_utime;
+ ts += ws_record.times.tms_stime;
+ tcu += ws_record.times.tms_cutime;
+ tcs += ws_record.times.tms_cstime;
#endif /* HAVE_TIMES */
count += lres;
bcount += bytes;
for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
for (j = 0; j < HARD_THREAD_LIMIT; ++j) {
- score_record = ap_scoreboard_image->servers[i][j];
+ ws_record = ap_scoreboard_image->servers[i][j];
ps_record = ap_scoreboard_image->parent[i];
- vhost = score_record.vhostrec;
+ vhost = ws_record.vhostrec;
if (ps_record.generation != ap_my_generation) {
vhost = NULL;
}
#if defined(NO_GETTIMEOFDAY)
#ifdef HAVE_TIMES
- if (score_record.start_time == (clock_t) 0)
+ if (ws_record.start_time == (clock_t) 0)
#endif /* HAVE_TIMES */
req_time = 0L;
#ifdef HAVE_TIMES
else {
- req_time = score_record.stop_time - score_record.start_time;
+ req_time = ws_record.stop_time - ws_record.start_time;
req_time = (req_time * 1000) / (int) tick;
}
#endif /* HAVE_TIMES */
#else
- if (score_record.start_time == 0L &&
- score_record.start_time == 0L)
+ if (ws_record.start_time == 0L &&
+ ws_record.start_time == 0L)
req_time = 0L;
else
req_time =
- ((score_record.stop_time - score_record.start_time) * 1000) +
- ((score_record.stop_time - score_record.start_time) / 1000);
+ ((ws_record.stop_time - ws_record.start_time) * 1000) +
+ ((ws_record.stop_time - ws_record.start_time) / 1000);
#endif
if (req_time < 0L)
req_time = 0L;
- lres = score_record.access_count;
- my_lres = score_record.my_access_count;
- conn_lres = score_record.conn_count;
- bytes = score_record.bytes_served;
- my_bytes = score_record.my_bytes_served;
- conn_bytes = score_record.conn_bytes;
- if (lres != 0 || (score_record.status != SERVER_READY
- && score_record.status != SERVER_DEAD)) {
+ lres = ws_record.access_count;
+ my_lres = ws_record.my_access_count;
+ conn_lres = ws_record.conn_count;
+ bytes = ws_record.bytes_served;
+ my_bytes = ws_record.my_bytes_served;
+ conn_bytes = ws_record.conn_bytes;
+ if (lres != 0 || (ws_record.status != SERVER_READY
+ && ws_record.status != SERVER_DEAD)) {
if (!short_report) {
if (no_table_report) {
- if (score_record.status == SERVER_DEAD)
+ if (ws_record.status == SERVER_DEAD)
ap_rprintf(r,
"<b>Server %d-%d</b> (-): %d|%lu|%lu [",
i, (int) ps_record.generation, (int) conn_lres,
ps_record.pid,
(int) conn_lres, my_lres, lres);
- switch (score_record.status) {
+ switch (ws_record.status) {
case SERVER_READY:
ap_rputs("Ready", r);
break;
#else
ap_rprintf(r, "] u%g s%g cu%g cs%g\n %ld %ld (",
- score_record.times.tms_utime / tick,
- score_record.times.tms_stime / tick,
- score_record.times.tms_cutime / tick,
- score_record.times.tms_cstime / tick,
+ ws_record.times.tms_utime / tick,
+ ws_record.times.tms_stime / tick,
+ ws_record.times.tms_cutime / tick,
+ ws_record.times.tms_cstime / tick,
#endif
- (long)((nowtime - score_record.last_used) / APR_USEC_PER_SEC),
+ (long)((nowtime - ws_record.last_used) / APR_USEC_PER_SEC),
(long) req_time);
format_byte_out(r, conn_bytes);
ap_rputs("|", r);
format_byte_out(r, bytes);
ap_rputs(")\n", r);
ap_rprintf(r, " <i>%s {%s}</i> <b>[%s]</b><br>\n\n",
- ap_escape_html(r->pool, score_record.client),
- ap_escape_html(r->pool, score_record.request),
+ ap_escape_html(r->pool, ws_record.client),
+ ap_escape_html(r->pool, ws_record.request),
vhost ? ap_escape_html(r->pool,
vhost->server_hostname) : "(unavailable)");
}
else { /* !no_table_report */
- if (score_record.status == SERVER_DEAD)
+ if (ws_record.status == SERVER_DEAD)
ap_rprintf(r,
"<tr><td><b>%d-%d</b><td>-<td>%d/%lu/%lu",
i, (int) ps_record.generation,
ps_record.pid, (int) conn_lres,
my_lres, lres);
- switch (score_record.status) {
+ switch (ws_record.status) {
case SERVER_READY:
ap_rputs("<td>_", r);
break;
ap_rprintf(r, "\n<td>%.0f<td>%ld",
#else
ap_rprintf(r, "\n<td>%.2f<td>%ld<td>%ld",
- (score_record.times.tms_utime +
- score_record.times.tms_stime +
- score_record.times.tms_cutime +
- score_record.times.tms_cstime) / tick,
+ (ws_record.times.tms_utime +
+ ws_record.times.tms_stime +
+ ws_record.times.tms_cutime +
+ ws_record.times.tms_cstime) / tick,
#endif
- (long)((nowtime - score_record.last_used) / APR_USEC_PER_SEC),
+ (long)((nowtime - ws_record.last_used) / APR_USEC_PER_SEC),
(long) req_time);
ap_rprintf(r, "<td>%-1.1f<td>%-2.2f<td>%-2.2f\n",
(float) conn_bytes / KBYTE, (float) my_bytes / MBYTE,
(float) bytes / MBYTE);
- if (score_record.status == SERVER_BUSY_READ)
+ if (ws_record.status == SERVER_BUSY_READ)
ap_rprintf(r,
"<td>?<td nowrap>?<td nowrap>..reading.. </tr>\n\n");
else
ap_rprintf(r,
"<td>%s<td nowrap>%s<td nowrap>%s</tr>\n\n",
- ap_escape_html(r->pool, score_record.client),
+ ap_escape_html(r->pool, ws_record.client),
vhost ? ap_escape_html(r->pool,
vhost->server_hostname) : "(unavailable)",
- ap_escape_html(r->pool, score_record.request));
+ ap_escape_html(r->pool, ws_record.request));
} /* no_table_report */
} /* !short_report */
} /* if (<active child>) */
if (pchild) {
apr_pool_destroy(pchild);
}
- ap_scoreboard_image->servers[my_child_num][0].life_status = SB_WORKING;
+ ap_scoreboard_image->parent[my_child_num].process_status = SB_WORKING;
chdir_for_gprof();
exit(code);
}
static void please_die_gracefully(int sig)
{
/* clean_child_exit(0); */
- ap_scoreboard_image->servers[my_child_num][0].life_status = SB_IDLE_DIE;
+ ap_scoreboard_image->parent[my_child_num].process_status = SB_IDLE_DIE;
if (sig == SIGHUP) {
(void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num),
SERVER_GRACEFUL, (request_rec *) NULL);
static fd_set main_fds;
#define I_AM_TO_SHUTDOWN() \
-(ap_scoreboard_image->servers[my_child_num][0].life_status != SB_WORKING)
+(ap_scoreboard_image->parent[my_child_num].process_status != SB_WORKING)
int ap_graceful_stop_signalled(void)
{
apr_signal(SIGQUIT, SIG_DFL);
#endif
apr_signal(SIGTERM, just_die);
- ap_scoreboard_image->servers[slot][0].life_status = SB_WORKING;
+ ap_scoreboard_image->parent[slot].process_status = SB_WORKING;
child_main(slot);
}
apr_signal(SIGHUP, please_die_gracefully);
apr_signal(SIGWINCH, please_die_gracefully);
apr_signal(SIGTERM, just_die);
- ap_scoreboard_image->servers[slot][0].life_status = SB_WORKING;
+ ap_scoreboard_image->parent[slot].process_status = SB_WORKING;
child_main(slot);
}
#ifdef SCOREBOARD_FILE
lseek(scoreboard_fd, XtOffsetOf(scoreboard, parent[slot]), 0);
force_write(scoreboard_fd, &ap_scoreboard_image->parent[slot],
- sizeof(parent_score));
+ sizeof(process_score));
#endif
return 0;
int i;
int to_kill;
int idle_count;
- short_score *ss;
+ worker_score *ws;
int free_length;
int free_slots[MAX_SPAWN_RATE];
int last_non_dead;
if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate)
break;
- ss = &ap_scoreboard_image->servers[i][0];
- status = ss->status;
+ ws = &ap_scoreboard_image->servers[i][0];
+ status = ws->status;
if (status == SERVER_DEAD) {
/* try to keep children numbers as low as possible */
if (free_length < idle_spawn_rate) {
update_scoreboard_global();
for (index = 0; index < ap_daemons_limit; ++index) {
- ap_scoreboard_image->servers[index][0].life_status = SB_IDLE_DIE;
+ ap_scoreboard_image->parent[index].process_status = SB_IDLE_DIE;
}
if (is_graceful) {
int i;
int to_kill;
int idle_count;
- short_score *ss;
+ worker_score *ws;
int free_length;
int free_slots[MAX_SPAWN_RATE];
int last_non_dead;
if (i >= max_daemons_limit && free_length == idle_spawn_rate)
break;
- ss = &ap_scoreboard_image->servers[0][i];
- status = ss->status;
+ ws = &ap_scoreboard_image->servers[0][i];
+ status = ws->status;
if (status == SERVER_DEAD) {
/* try to keep children numbers as low as possible */
if (free_length < idle_spawn_rate) {
{
int i, j;
int idle_thread_count;
- short_score *ss;
+ worker_score *ws;
int free_length;
int free_slots[MAX_SPAWN_RATE];
int last_non_dead;
if (i >= ap_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;
+ ws = &ap_scoreboard_image->servers[i][j];
+ status = ws->status;
any_dying_threads = any_dying_threads || (status == SERVER_DEAD)
|| (status == SERVER_GRACEFUL);
}
static APR_INLINE void put_scoreboard_info(int child_num, int thread_num,
- short_score *new_score_rec)
+ worker_score *new_score_rec)
{
/* XXX - needs to be fixed to account for threads */
#ifdef SCOREBOARD_FILE
- lseek(scoreboard_fd, (long) child_num * sizeof(short_score), 0);
- force_write(scoreboard_fd, new_score_rec, sizeof(short_score));
+ lseek(scoreboard_fd, (long) child_num * sizeof(worker_score), 0);
+ force_write(scoreboard_fd, new_score_rec, sizeof(worker_score));
#endif
}
AP_DECLARE(void) ap_increment_counts(int child_num, int thread_num, request_rec *r)
{
- short_score *ss;
+ worker_score *ws;
- ss = &ap_scoreboard_image->servers[child_num][thread_num];
+ ws = &ap_scoreboard_image->servers[child_num][thread_num];
#ifdef HAVE_TIMES
- times(&ss->times);
+ times(&ws->times);
#endif
- ss->access_count++;
- ss->my_access_count++;
- ss->conn_count++;
- ss->bytes_served += r->bytes_sent;
- ss->my_bytes_served += r->bytes_sent;
- ss->conn_bytes += r->bytes_sent;
-
- put_scoreboard_info(child_num, thread_num, ss);
+ ws->access_count++;
+ ws->my_access_count++;
+ ws->conn_count++;
+ ws->bytes_served += r->bytes_sent;
+ ws->my_bytes_served += r->bytes_sent;
+ ws->conn_bytes += r->bytes_sent;
+
+ put_scoreboard_info(child_num, thread_num, ws);
}
AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid)
int ap_update_child_status(int child_num, int thread_num, int status, request_rec *r)
{
int old_status;
- short_score *ss;
- parent_score *ps;
+ worker_score *ws;
+ process_score *ps;
if (child_num < 0)
return -1;
- ss = &ap_scoreboard_image->servers[child_num][thread_num];
- old_status = ss->status;
- ss->status = status;
+ ws = &ap_scoreboard_image->servers[child_num][thread_num];
+ old_status = ws->status;
+ ws->status = status;
ps = &ap_scoreboard_image->parent[child_num];
if ((status == SERVER_READY || status == SERVER_ACCEPTING)
&& old_status == SERVER_STARTING) {
- ss->thread_num = child_num * HARD_SERVER_LIMIT + thread_num;
+ ws->thread_num = child_num * HARD_SERVER_LIMIT + thread_num;
ps->generation = ap_my_generation;
ps->worker_threads = ap_threads_per_child;
}
if (ap_extended_status) {
- ss->last_used = apr_time_now();
+ ws->last_used = apr_time_now();
if (status == SERVER_READY || status == SERVER_DEAD) {
/*
* Reset individual counters
*/
if (status == SERVER_DEAD) {
- ss->my_access_count = 0L;
- ss->my_bytes_served = 0L;
+ ws->my_access_count = 0L;
+ ws->my_bytes_served = 0L;
}
- ss->conn_count = (unsigned short) 0;
- ss->conn_bytes = (unsigned long) 0;
+ ws->conn_count = (unsigned short) 0;
+ ws->conn_bytes = (unsigned long) 0;
}
if (r) {
conn_rec *c = r->connection;
- apr_cpystrn(ss->client, ap_get_remote_host(c, r->per_dir_config,
- REMOTE_NOLOOKUP, NULL), sizeof(ss->client));
+ apr_cpystrn(ws->client, ap_get_remote_host(c, r->per_dir_config,
+ REMOTE_NOLOOKUP, NULL), sizeof(ws->client));
if (r->the_request == NULL) {
- apr_cpystrn(ss->request, "NULL", sizeof(ss->request));
+ apr_cpystrn(ws->request, "NULL", sizeof(ws->request));
} else if (r->parsed_uri.password == NULL) {
- apr_cpystrn(ss->request, r->the_request, sizeof(ss->request));
+ apr_cpystrn(ws->request, r->the_request, sizeof(ws->request));
} else {
/* Don't reveal the password in the server-status view */
- apr_cpystrn(ss->request, apr_pstrcat(r->pool, r->method, " ",
+ apr_cpystrn(ws->request, apr_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));
+ sizeof(ws->request));
}
- ss->vhostrec = r->server;
+ ws->vhostrec = r->server;
}
}
- put_scoreboard_info(child_num, thread_num, ss);
+ put_scoreboard_info(child_num, thread_num, ws);
return old_status;
}
void ap_time_process_request(int child_num, int thread_num, int status)
{
- short_score *ss;
+ worker_score *ws;
if (child_num < 0)
return;
- ss = &ap_scoreboard_image->servers[child_num][thread_num];
+ ws = &ap_scoreboard_image->servers[child_num][thread_num];
if (status == START_PREQUEST) {
- ss->start_time = apr_time_now();
+ ws->start_time = apr_time_now();
}
else if (status == STOP_PREQUEST) {
- ss->stop_time = apr_time_now();
+ ws->stop_time = apr_time_now();
}
- put_scoreboard_info(child_num, thread_num, ss);
+ put_scoreboard_info(child_num, thread_num, ws);
}