## 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] */