rbb         99/03/18 08:35:48

  Modified:    pthreads/src/modules/standard mod_unique_id.c
  Log:
  Modifications to make mod_unique_id thread safe.  This should work on Windows,
  but no garauntees.  I haven't verified it will always give a unique ID, but
  the logic is good.  I'll write some test cases to see if I can make it fail
  later.
  
  Revision  Changes    Path
  1.3       +28 -11    apache-apr/pthreads/src/modules/standard/mod_unique_id.c
  
  Index: mod_unique_id.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_unique_id.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- mod_unique_id.c   1999/02/07 06:29:56     1.2
  +++ mod_unique_id.c   1999/03/18 16:35:48     1.3
  @@ -67,17 +67,24 @@
   #include "http_log.h"
   #include "multithread.h"
   
  -#ifdef MULTITHREAD
  -#error sorry this module does not support multithreaded servers yet
  -#endif
  -
   typedef struct {
       unsigned int stamp;
       unsigned int in_addr;
       unsigned int pid;
       unsigned short counter;
  +    unsigned int thread_index;
   } unique_id_rec;
   
  +/* We are using thread_index (the index into the scoreboard), because we
  + * cannont garauntee the thread_id will be an integer.
  + *
  + * This code looks like it won't give a unique ID with the new thread logic.
  + * It will.  The reason is, we don't increment the counter in a thread_safe 
  + * manner.  Because the thread_index is also in the unique ID now, this does
  + * not matter.  In order for the id to not be unique, the same thread would
  + * have to get the same counter twice in the same second. 
  + */
  +
   /* Comments:
    *
    * We want an identifier which is unique across all hits, everywhere.
  @@ -143,12 +150,12 @@
   
   static unsigned global_in_addr;
   
  -static APACHE_TLS unique_id_rec cur_unique_id;
  +static unique_id_rec cur_unique_id;
   
   /*
    * Number of elements in the structure unique_id_rec.
    */
  -#define UNIQUE_ID_REC_MAX 4
  +#define UNIQUE_ID_REC_MAX 5 
   
   static unsigned short unique_id_rec_offset[UNIQUE_ID_REC_MAX],
                         unique_id_rec_size[UNIQUE_ID_REC_MAX],
  @@ -177,8 +184,11 @@
       unique_id_rec_size[2] = sizeof(cur_unique_id.pid);
       unique_id_rec_offset[3] = XtOffsetOf(unique_id_rec, counter);
       unique_id_rec_size[3] = sizeof(cur_unique_id.counter);
  +    unique_id_rec_offset[4] = XtOffsetOf(unique_id_rec, thread_index);
  +    unique_id_rec_size[4] = sizeof(cur_unique_id.thread_index);
       unique_id_rec_total_size = unique_id_rec_size[0] + unique_id_rec_size[1] 
+
  -                               unique_id_rec_size[2] + unique_id_rec_size[3];
  +                               unique_id_rec_size[2] + unique_id_rec_size[3] 
+
  +                               unique_id_rec_size[4];
   
       /*
        * Calculate the size of the structure when uuencoded.
  @@ -316,6 +326,7 @@
        * Buffer padded with two final bytes, used to copy the unique_id_red
        * structure without the internal paddings that it could have.
        */
  +    unique_id_rec new_unique_id;
       struct {
        unique_id_rec foo;
        unsigned char pad[2];
  @@ -332,16 +343,21 @@
        ap_table_setn(r->subprocess_env, "UNIQUE_ID", e);
        return DECLINED;
       }
  +    
  +    new_unique_id.in_addr = cur_unique_id.in_addr;
  +    new_unique_id.pid = cur_unique_id.pid;
  +    new_unique_id.counter = cur_unique_id.counter;
   
  -    cur_unique_id.stamp = htonl((unsigned int)r->request_time);
  +    new_unique_id.stamp = htonl((unsigned int)r->request_time);
  +    new_unique_id.thread_index = htonl((unsigned 
int)r->connection->thread_num);
   
       /* we'll use a temporal buffer to avoid uuencoding the possible internal
        * paddings of the original structure */
       x = (unsigned char *) &paddedbuf;
  -    y = (unsigned char *) &cur_unique_id;
  +    y = (unsigned char *) &new_unique_id;
       k = 0;
       for (i = 0; i < UNIQUE_ID_REC_MAX; i++) {
  -        y = ((unsigned char *) &cur_unique_id) + unique_id_rec_offset[i];
  +        y = ((unsigned char *) &new_unique_id) + unique_id_rec_offset[i];
           for (j = 0; j < unique_id_rec_size[i]; j++, k++) {
               x[k] = y[j];
           }
  @@ -370,7 +386,8 @@
       ap_table_setn(r->subprocess_env, "UNIQUE_ID", str);
   
       /* and increment the identifier for the next call */
  -    counter = ntohs(cur_unique_id.counter) + 1;
  +
  +    counter = ntohs(new_unique_id.counter) + 1;
       cur_unique_id.counter = htons(counter);
   
       return DECLINED;
  
  
  

Reply via email to