Commit 9ed73300 authored by Paul J. Reder's avatar Paul J. Reder
Browse files

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]


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@89115 13f79535-47bb-0310-9956-ffa450edef68
parent 63f3719a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
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
+22 −17
Original line number Diff line number Diff line
@@ -106,8 +106,8 @@ extern "C" {
 *
 * 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) {
@@ -132,8 +132,15 @@ typedef enum {
#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;
@@ -145,7 +152,6 @@ typedef struct {
    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
@@ -156,7 +162,8 @@ typedef struct {
    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;
@@ -165,15 +172,20 @@ typedef struct {
} 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;

@@ -184,13 +196,6 @@ typedef struct {
    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
+45 −45
Original line number Diff line number Diff line
@@ -251,8 +251,8 @@ static int status_handler(request_rec *r)
#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;
@@ -317,9 +317,9 @@ static int status_handler(request_rec *r)
        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)
@@ -327,14 +327,14 @@ static int status_handler(request_rec *r)
	    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;
@@ -510,47 +510,47 @@ static int status_handler(request_rec *r)

	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,
@@ -563,7 +563,7 @@ static int status_handler(request_rec *r)
				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;
@@ -601,12 +601,12 @@ static int status_handler(request_rec *r)
#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);
@@ -615,13 +615,13 @@ static int status_handler(request_rec *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,
@@ -634,7 +634,7 @@ static int status_handler(request_rec *r)
				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;
@@ -671,26 +671,26 @@ static int status_handler(request_rec *r)
			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>) */
+10 −10
Original line number Diff line number Diff line
@@ -232,7 +232,7 @@ static void clean_child_exit(int code)
    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);
}
@@ -378,7 +378,7 @@ static void just_die(int sig)
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);
@@ -534,7 +534,7 @@ static int requests_this_child;
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)
{
@@ -846,7 +846,7 @@ static int make_child(server_rec *s, int slot)
	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);
    }

@@ -897,7 +897,7 @@ static int make_child(server_rec *s, int 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);
    }

@@ -905,7 +905,7 @@ static int make_child(server_rec *s, int 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;
@@ -946,7 +946,7 @@ static void perform_idle_server_maintenance(void)
    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;
@@ -966,8 +966,8 @@ static void perform_idle_server_maintenance(void)

	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) {
@@ -1260,7 +1260,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
    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) {
+3 −3
Original line number Diff line number Diff line
@@ -777,7 +777,7 @@ static void perform_idle_server_maintenance(void)
    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;
@@ -796,8 +796,8 @@ static void perform_idle_server_maintenance(void)

	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) {
Loading