You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rb...@locus.apache.org on 2000/03/30 22:51:27 UTC

cvs commit: apache-2.0/src/modules/mpm/prefork prefork.c scoreboard.h

rbb         00/03/30 12:51:26

  Modified:    src/modules/mpm/prefork prefork.c scoreboard.h
  Log:
  A very first shot at implementing the status API for the prefork mpm.
  This is without a doubt a bad implementation, but it works, and the
  server compiles with mod_status enabled.
  
  Revision  Changes    Path
  1.72      +135 -10   apache-2.0/src/modules/mpm/prefork/prefork.c
  
  Index: prefork.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/mpm/prefork/prefork.c,v
  retrieving revision 1.71
  retrieving revision 1.72
  diff -u -r1.71 -r1.72
  --- prefork.c	2000/03/30 15:30:35	1.71
  +++ prefork.c	2000/03/30 20:51:23	1.72
  @@ -81,7 +81,6 @@
   /* TODO: this is a cobbled together prefork MPM example... it should mostly
    * TODO: behave like apache-1.3... here's a short list of things I think
    * TODO: need cleaning up still:
  - * TODO: - use ralf's mm stuff for the shared mem and mutexes
    * TODO: - clean up scoreboard stuff when we figure out how to do it in 2.0
    */
   
  @@ -127,6 +126,7 @@
   static int ap_daemons_limit=0;
   static time_t ap_restart_time=0;
   static int ap_extended_status = 0;
  +static int maintain_connection_status = 1;
   
   /*
    * The max child slot ever assigned, preserved across restarts.  Necessary
  @@ -184,6 +184,7 @@
   #endif /* TPF */
   
   static scoreboard *ap_scoreboard_image = NULL;
  +static new_scoreboard *ap_new_scoreboard_image = NULL;
   
   #ifdef GPROF
   /* 
  @@ -922,13 +923,14 @@
       const char *fname;
   
       fname = ap_server_root_relative(p, ap_scoreboard_fname);
  -    if (ap_shm_init(&scoreboard_shm, SCOREBOARD_SIZE + 40, fname, p) != APR_SUCCESS) {
  +    if (ap_shm_init(&scoreboard_shm, SCOREBOARD_SIZE + NEW_SCOREBOARD_SIZE + 40, fname, p) != APR_SUCCESS) {
   	ap_snprintf(buf, sizeof(buf), "%s: could not open(create) scoreboard",
   		    ap_server_argv0);
   	perror(buf);
   	exit(APEXIT_INIT);
       }
       ap_scoreboard_image = ap_shm_malloc(scoreboard_shm, SCOREBOARD_SIZE); 
  +    ap_new_scoreboard_image = ap_shm_malloc(scoreboard_shm, NEW_SCOREBOARD_SIZE); 
       if (ap_scoreboard_image == NULL) {
   	ap_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard",
   		    ap_server_argv0);
  @@ -2156,6 +2158,22 @@
       return 0;
   }
   
  +/* Useful to erase the status of children that might be from previous
  + * generations */
  +static void ap_prefork_force_reset_connection_status(long conn_id)
  +{
  +    int i;
  +
  +    for (i = 0; i < STATUSES_PER_CONNECTION; i++) {
  +        ap_new_scoreboard_image->table[conn_id][i].key[0] = '\0';
  +    }                                                                           }
  +
  +void ap_reset_connection_status(long conn_id)
  +{
  +    if (maintain_connection_status) {
  +        ap_prefork_force_reset_connection_status(conn_id);
  +    }
  +}
   
   /*****************************************************************
    * Executive routines.
  @@ -2236,6 +2254,7 @@
   	    ap_sync_scoreboard_image();
   	    child_slot = find_child_by_pid(pid);
   	    if (child_slot >= 0) {
  +                ap_prefork_force_reset_connection_status(child_slot);
   		(void) ap_update_child_status(child_slot, SERVER_DEAD,
   					    (request_rec *) NULL);
   		if (remaining_children_to_start
  @@ -2551,22 +2570,128 @@
   }
   
   /* Stub functions until this MPM supports the connection status API */
  +/* Don't mess with the string you get back from this function */
  +const char *ap_get_connection_status(long conn_id, const char *key)
  +{
  +    int i = 0;
  +    status_table_entry *ss;
   
  -API_EXPORT(void) ap_update_connection_status(long conn_id, const char *key, \
  -                                             const char *value)
  +    if (!maintain_connection_status) return "";
  +    while (i < STATUSES_PER_CONNECTION) {
  +        ss = &(ap_new_scoreboard_image->table[conn_id][i]);
  +        if (ss->key[0] == '\0') {
  +            break;
  +        }
  +        if (0 == strcmp(ss->key, key)) {
  +            return ss->value;
  +        }
  +    }
  +
  +    return NULL;
  +}
  +
  +ap_array_header_t *ap_get_connections(ap_context_t *p)
   {
  -    /* NOP */
  +    int i;
  +    ap_array_header_t *connection_list;
  +    long *array_slot;
  +
  +    connection_list = ap_make_array(p, 0, sizeof(long));
  +    /* We assume that there is a connection iff it has an entry in the status
  +     * table. Connections without any status sound problematic to me, so this
  +     * is probably for the best. - manoj */
  +    for (i = 0; i < max_daemons_limit; i++) {
  +         if (ap_new_scoreboard_image->table[i][0].key[0] != '\0') {
  +            array_slot = ap_push_array(connection_list);
  +            *array_slot = i;
  +        }
  +    }
  +    return connection_list;
   }
   
  -ap_array_header_t *ap_get_status_table(ap_context_t *p)
  +ap_array_header_t *ap_get_connection_keys(ap_context_t *p, long conn_id)
   {
  -    /* NOP */
  -    return NULL;
  +    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_new_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;
  +}
  +
  +/* Note: no effort is made here to prevent multiple threads from messing with
  + * a single connection at the same time. ap_update_connection_status should
  + * only be called by the thread that owns the connection */
  +
  +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_new_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++;
  +    }
  +    /* Not found. Add an entry for this value */
  +    if (i >= STATUSES_PER_CONNECTION) {
  +        /* No room. Oh well, not much anyone can do about it. */
  +        return;
  +    }
  +    ap_cpystrn(ss->key, key, KEY_LENGTH);
  +    ap_cpystrn(ss->value, value, VALUE_LENGTH);
  +    return;
   }
   
  -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));
  +
  +    /* Go ahead and return what's in the connection status table even if we
  +     * aren't maintaining it. We can at least look at what children from
  +     * previous generations are up to. */
  +
  +    for (i = 0; i < max_daemons_limit; i++) {
  +        if (ap_new_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_new_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;
   }
   
   static const command_rec prefork_cmds[] = {
  
  
  
  1.7       +14 -0     apache-2.0/src/modules/mpm/prefork/scoreboard.h
  
  Index: scoreboard.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/mpm/prefork/scoreboard.h,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- scoreboard.h	2000/03/10 00:07:06	1.6
  +++ scoreboard.h	2000/03/30 20:51:23	1.7
  @@ -190,7 +190,21 @@
       global_score global;
   } scoreboard;
   
  +#define KEY_LENGTH 16
  +#define VALUE_LENGTH 64
  +typedef struct {
  +    char key[KEY_LENGTH];
  +    char value[VALUE_LENGTH];                                                   } status_table_entry;
  +
  +#define STATUSES_PER_CONNECTION 10
  +
  +typedef struct {
  +    status_table_entry
  +        table[HARD_SERVER_LIMIT][STATUSES_PER_CONNECTION];
  +} new_scoreboard;
  +
   #define SCOREBOARD_SIZE		sizeof(scoreboard)
  +#define NEW_SCOREBOARD_SIZE		sizeof(new_scoreboard)
   #ifdef TPF
   #define SCOREBOARD_NAME		"SCOREBRD"
   #define SCOREBOARD_FRAMES		SCOREBOARD_SIZE/4095 + 1