modules/ta/ta.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. ta_findonly_l
  2. ta_findcreate_l
  3. ta_remove_l
  4. ta_setactivity_l
  5. ta_print_header
  6. ta_printone_l
  7. TA_add
  8. TA_delete
  9. TA_setactivity
  10. TA_setcondat
  11. TA_increment
  12. TA_tostring
  13. TA_trigger

   1 /***************************************
   2   $Revision: 1.4 $
   3 
   4   thread accounting (ta). ta.c - functions to keep track of activities
   5                             of threads within the server
   6 
   7   Status: NOT REVUED, TESTED, COMPLETE
   8 
   9   Design and implementation by: Marek Bukowy
  10 
  11   ******************/ /******************
  12   Copyright (c) 1999                              RIPE NCC
  13  
  14   All Rights Reserved
  15   
  16   Permission to use, copy, modify, and distribute this software and its
  17   documentation for any purpose and without fee is hereby granted,
  18   provided that the above copyright notice appear in all copies and that
  19   both that copyright notice and this permission notice appear in
  20   supporting documentation, and that the name of the author not be
  21   used in advertising or publicity pertaining to distribution of the
  22   software without specific, written prior permission.
  23   
  24   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  25   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  26   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  27   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  28   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  29   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  30   ***************************************/
  31 
  32 #define TA_IMPL
  33 #include <ta.h>
  34 
  35 
  36 static
  37 ta_str_t *ta_findonly_l( GList **list, pthread_t thread_id )
     /* [<][>][^][v][top][bottom][index][help] */
  38 {
  39   GList *item;
  40 
  41   /* try to find first */
  42   for(item = g_list_first(*list);
  43       item != NULL;
  44       item = g_list_next(item)) {
  45     ta_str_t *tas = (ta_str_t *) (item->data);
  46 
  47     if( tas->thread_id == thread_id ) {
  48       return tas;
  49     }
  50   }
  51   return NULL;
  52 }
  53 
  54 static
  55 ta_str_t *ta_findcreate_l( GList **list, pthread_t thread_id )
     /* [<][>][^][v][top][bottom][index][help] */
  56 {
  57   ta_str_t *newtas;
  58 
  59   if( (newtas = ta_findonly_l(list, thread_id)) == NULL) {
  60     
  61     /* not found => add */  /* zero everything*/
  62     dieif( !NOERR( wr_calloc( (void **) &newtas, 1, sizeof( ta_str_t ))));
  63     newtas->thread_id = thread_id;
  64     
  65     *list = g_list_append( *list, newtas );
  66   }
  67 
  68   return newtas;
  69 }
  70 
  71 
  72 /* find and remove */
  73 static
  74 void ta_remove_l(GList **list, pthread_t thread_id )
     /* [<][>][^][v][top][bottom][index][help] */
  75 { 
  76  GList *item;
  77 
  78  for(item = g_list_first(*list);
  79      item != NULL;
  80      item = g_list_next(item)) {
  81    ta_str_t *tas = (ta_str_t *) (item->data);
  82 
  83    if( tas->thread_id == thread_id ) {
  84      *list = g_list_remove_link(*list, item);
  85      wr_clear_list( &item );
  86      break;
  87    }
  88  }
  89    
  90  return;
  91 }
  92 
  93 /* set the activity field */
  94 static
  95 void ta_setactivity_l(ta_str_t *tas, char *activity)
     /* [<][>][^][v][top][bottom][index][help] */
  96 {
  97   char *nl;
  98 
  99   strncpy(tas->activity, activity, TA_ACT_LEN-1);
 100   tas->activity[TA_ACT_LEN]=0;
 101   /* convert last newline to a space, if any */
 102   if( (nl=strrchr(tas->activity, '\n')) != NULL ) {
 103     *nl=' ';
 104   }
 105 }
 106 
 107 
 108 #define TA_HEADER "%-8s %15s %4s %4s %5s %5s %4s %5s %s\n"
 109 #define TA_FORMAT "%-8s %15s %4d %4d %5.1f %5.1f %4d %5.2f %s\n"
 110 
 111 static 
 112 void ta_print_header(char *buf, int length)
     /* [<][>][^][v][top][bottom][index][help] */
 113 {
 114   snprintf(buf, length, TA_HEADER,
 115            "type", "from", "sock", "thr", "sess", "task", "#", 
 116            "avg", "current"
 117            ); 
 118 }
 119 
 120 /* fill in one entry */
 121 static
 122 void ta_printone_l(ta_str_t *tas, char *buf, int length, 
     /* [<][>][^][v][top][bottom][index][help] */
 123                    ut_timer_t *reftime)
 124 {
 125   float session, task;  /* duration of the session/task */
 126   char *address = SK_getpeername(tas->sock); /* allocated! */
 127   /* can be NULL for example if the socket has just closed
 128      or the file descriptor is not a socket */
 129 
 130   session = UT_timediff( &tas->sessionstart, reftime );
 131   task    = UT_timediff( &tas->taskstart, reftime );
 132 
 133   snprintf(buf, length, TA_FORMAT ,
 134            tas->type,
 135            address ? address : "", 
 136            tas->sock, 
 137            tas->thread_id, 
 138            session,
 139            task,
 140            tas->tasks,
 141            (tas->tasks > 0) ? session / tas->tasks : 0,
 142            tas->activity);
 143   
 144   if (address) {
 145     wr_free(address);
 146   }
 147 }
 148 
 149 /* PUBLIC adding function */
 150 void TA_add(int sock, char *type)
     /* [<][>][^][v][top][bottom][index][help] */
 151 {
 152   ta_str_t *newtas;
 153   
 154   /* lock the list */
 155   pthread_mutex_lock( &ta_mutex );
 156   
 157   /* find/create node and set peer/thread_id */
 158   newtas = ta_findcreate_l( &ta_list, pthread_self());
 159   newtas->sock = sock;
 160   newtas->tasks = 0;
 161   newtas->condat = NULL;
 162   UT_timeget( &newtas->sessionstart );
 163   UT_timeget( &newtas->taskstart ); /* just to get it a reasonable value */
 164 
 165   snprintf(newtas->type, TA_TYPE_LEN, type);
 166   ta_setactivity_l(newtas,"--");
 167   
 168   /* unlock */
 169   pthread_mutex_unlock( &ta_mutex );
 170 }
 171 
 172 
 173 /* PUBLIC deletion function */
 174 void TA_delete(void)
     /* [<][>][^][v][top][bottom][index][help] */
 175 {
 176   /* lock the list */
 177   pthread_mutex_lock( &ta_mutex );
 178   
 179   /* find & remove */
 180   ta_remove_l( &ta_list, pthread_self() );
 181   
 182   /* unlock */
 183   pthread_mutex_unlock( &ta_mutex );
 184 }
 185 
 186 
 187 /* PUBLIC activity-setting function */
 188 void TA_setactivity(char *activity)
     /* [<][>][^][v][top][bottom][index][help] */
 189 {
 190   ta_str_t *newtas;
 191 
 192   /* lock the list */
 193   pthread_mutex_lock( &ta_mutex );
 194   
 195   /* find */
 196   newtas = ta_findcreate_l( &ta_list, pthread_self());
 197   
 198   /* set the activity field */
 199   ta_setactivity_l(newtas, activity);
 200 
 201   /* unlock */
 202   pthread_mutex_unlock( &ta_mutex );
 203 }
 204 
 205 /* PUBLIC condat-setting function */
 206 void TA_setcondat(sk_conn_st *condat)
     /* [<][>][^][v][top][bottom][index][help] */
 207 {
 208   ta_str_t *newtas;
 209 
 210   /* lock the list */
 211   pthread_mutex_lock( &ta_mutex );
 212   
 213   /* find */
 214   newtas = ta_findcreate_l( &ta_list, pthread_self());
 215   
 216   /* set the condat field */
 217   newtas->condat = condat;
 218 
 219   /* unlock */
 220   pthread_mutex_unlock( &ta_mutex );
 221 }
 222 
 223 
 224 void TA_increment(void)
     /* [<][>][^][v][top][bottom][index][help] */
 225 {
 226   ta_str_t *newtas;
 227 
 228   /* lock the list */
 229   pthread_mutex_lock( &ta_mutex );
 230   
 231   /* find */
 232   newtas = ta_findcreate_l( &ta_list, pthread_self());
 233   /* increment task */
 234   newtas->tasks++;
 235   /* set task starting time */
 236   UT_timeget( &newtas->taskstart );
 237 
 238   /* unlock */
 239   pthread_mutex_unlock( &ta_mutex );
 240 }
 241 
 242 char * TA_tostring(void)
     /* [<][>][^][v][top][bottom][index][help] */
 243 {
 244   GList *item;
 245   char *bigbuf = NULL;
 246   char smallbuf[TA_PRINT_LEN];
 247   ut_timer_t reftime;
 248 
 249   ta_print_header(smallbuf, TA_PRINT_LEN);
 250   dieif( !NOERR(wr_malloc( (void **) &bigbuf, strlen(smallbuf)+2 )));
 251   strcpy(bigbuf, smallbuf);
 252   strcat(bigbuf, "\n");
 253   
 254   /* lock the list */
 255   pthread_mutex_lock( &ta_mutex );
 256   
 257   /* get reference time */
 258   UT_timeget( &reftime );
 259   
 260   /* iterate */
 261   for(item = g_list_first(ta_list);
 262       item != NULL;
 263       item = g_list_next(item)) {
 264     ta_str_t *tas = (ta_str_t *) (item->data);
 265     int smalllen;
 266     int biglen = ( bigbuf == NULL ) ? 0 : strlen(bigbuf);
 267 
 268     ta_printone_l(tas, smallbuf, TA_PRINT_LEN, &reftime);
 269     smalllen = strlen(smallbuf);
 270 
 271     dieif( !NOERR(wr_realloc( (void **) &bigbuf, biglen+smalllen+3 )));
 272     
 273     strcat(bigbuf, smallbuf);
 274   }
 275   /* unlock */
 276   pthread_mutex_unlock( &ta_mutex );
 277   
 278   return bigbuf;
 279 }
 280 
 281 /* 
 282    find a thread of the given type, socket file descriptor and thread id
 283    and execute the watchdog's triggers if it's defined.
 284 */
 285 
 286 void TA_trigger(char *type, int sock, pthread_t thread_id)
     /* [<][>][^][v][top][bottom][index][help] */
 287 { 
 288   ta_str_t *tas;
 289 
 290   /* lock the list */
 291   pthread_mutex_lock( &ta_mutex );
 292   
 293   if( (tas = ta_findonly_l(&ta_list, thread_id)) != NULL
 294       && tas->sock == sock
 295       && strcmp(tas->type, type) == 0
 296       && tas->condat != NULL
 297       && tas->condat->sock == sock
 298       ) {
 299     SK_watchtrigger(tas->condat);
 300   }
 301   
 302   /* unlock */
 303   pthread_mutex_unlock( &ta_mutex );
 304   
 305 }

/* [<][>][^][v][top][bottom][index][help] */