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/31 00:16:38 UTC

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

rbb         00/03/30 14:16:38

  Modified:    src/modules/mpm/mpmt_pthread mpmt_pthread.c scoreboard.c
                        scoreboard.h
  Log:
  An initial implementation for the mpmt_pthread mod_status API.  Again,
  this is a working implementation, but it is almost definately not a
  complete implementation.
  
  Revision  Changes    Path
  1.58      +1 -6      apache-2.0/src/modules/mpm/mpmt_pthread/mpmt_pthread.c
  
  Index: mpmt_pthread.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/mpm/mpmt_pthread/mpmt_pthread.c,v
  retrieving revision 1.57
  retrieving revision 1.58
  diff -u -r1.57 -r1.58
  --- mpmt_pthread.c	2000/03/30 15:30:34	1.57
  +++ mpmt_pthread.c	2000/03/30 22:16:37	1.58
  @@ -1266,6 +1266,7 @@
               /* non-fatal death... note that it's gone in the scoreboard. */
               child_slot = find_child_by_pid(pid);
               if (child_slot >= 0) {
  +                ap_mpmt_pthread_force_reset_connection_status(child_slot);
                   for (i = 0; i < ap_threads_per_child; i++)
                       ap_update_child_status(child_slot, i, SERVER_DEAD, (request_rec *) NULL);
                   
  @@ -1329,12 +1330,6 @@
                        "pipe: (pipe_of_death)");
           exit(1);
       }
  -/*  XXXXXX  Removed because these functions don't exist anymore.  When
  -    These pipes are changed to apr_types, these functions won't be needed
  -    anyway.
  -    ap_note_cleanups_for_fd(pconf, pipe_of_death[0]);
  -    ap_note_cleanups_for_fd(pconf, pipe_of_death[1]);
  -*/
   
       if (fcntl(pipe_of_death[0], F_SETFD, O_NONBLOCK) == -1) {
           ap_log_error(APLOG_MARK, APLOG_ERR, errno,
  
  
  
  1.18      +137 -8    apache-2.0/src/modules/mpm/mpmt_pthread/scoreboard.c
  
  Index: scoreboard.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/mpm/mpmt_pthread/scoreboard.c,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- scoreboard.c	2000/03/22 11:36:52	1.17
  +++ scoreboard.c	2000/03/30 22:16:37	1.18
  @@ -12,6 +12,8 @@
   #include <sys/types.h>
   
   scoreboard *ap_scoreboard_image = NULL;
  +new_scoreboard *ap_new_scoreboard_image = NULL;
  +static int maintain_connection_status = 1;
   API_VAR_IMPORT char *ap_scoreboard_fname;
   /*****************************************************************
    *
  @@ -40,14 +42,15 @@
       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);
  -    if (ap_scoreboard_image == NULL) {
  +    ap_new_scoreboard_image = ap_shm_malloc(scoreboard_shm, NEW_SCOREBOARD_SIZE);
  +    if (ap_scoreboard_image == NULL || ap_new_scoreboard_image == NULL) {
           ap_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard",
                       ap_server_argv0);
           perror(buf);
  @@ -235,17 +238,143 @@
       }
       put_scoreboard_info(child_num, thread_num, ss);
   }
  +
  +/* Useful to erase the status of children that might be from previous
  + * generations */
  +void ap_mpmt_pthread_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_mpmt_pthread_force_reset_connection_status(conn_id);
  +    }
  +}
  +
  +/* 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;
  +
  +    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)
  +{
  +    int i;
  +    ap_array_header_t *connection_list;
  +    long *array_slot;
  +    int max_daemons_limit = ap_get_max_daemons();
   
  -/* Stub functions until this MPM supports the connection status API */
  +    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*HARD_THREAD_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;
  +}
   
  -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_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;
   }
   
  -API_EXPORT(void) ap_reset_connection_status(long conn_id)
  +/* 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;
  +}
  +
  +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;
  +    int max_daemons_limit = ap_get_max_daemons();
  +    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*HARD_THREAD_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;
   }
  +
   
  
  
  
  1.10      +17 -0     apache-2.0/src/modules/mpm/mpmt_pthread/scoreboard.h
  
  Index: scoreboard.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/mpm/mpmt_pthread/scoreboard.h,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- scoreboard.h	2000/03/10 00:07:04	1.9
  +++ scoreboard.h	2000/03/30 22:16:37	1.10
  @@ -193,7 +193,22 @@
       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*HARD_THREAD_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
  @@ -203,6 +218,8 @@
   void reinit_scoareboard(ap_context_t *p);
   void cleanup_scoreboard(void);
   API_EXPORT(void) ap_sync_scoreboard_image(void);
  +void ap_mpmt_pthread_force_reset_connection_status(long conn_id);
  +
   
   #if defined(USE_OS2_SCOREBOARD)
   caddr_t create_shared_heap(const char *name, size_t size);