## modules/ta/ta.c

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

## FUNCTIONS

This source file includes following functions.

1. ta_findcreate_l
2. ta_remove_l
3. ta_setactivity_l
4. ta_print_header
5. ta_printone_l
6. TA_add
7. TA_delete
8. TA_setactivity
9. TA_increment
10. TA_tostring

       1 /***************************************
       2   $Revision: 1.2 $
       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 static
      36 ta_str_t *ta_findcreate_l( GList **list, pthread_t thread_id )
         /* [<][>][^][v][top][bottom][index][help] */
      37 {
      38   GList *item;
      39   ta_str_t *newtas;
      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
      52   /* not found => add */  /* zero everything*/
      53   dieif( !NOERR( wr_calloc( (void **) &newtas, 1, sizeof( ta_str_t ))));
      54   newtas->thread_id = thread_id;
      55
      56   *list = g_list_append( *list, newtas );
      57
      58   return newtas;
      59 }
      60
      61
      62 /* find and remove */
      63 static
      64 void ta_remove_l(GList **list, pthread_t thread_id )
         /* [<][>][^][v][top][bottom][index][help] */
      65 {
      66  GList *item;
      67
      68  for(item = g_list_first(*list);
      69      item != NULL;
      70      item = g_list_next(item)) {
      71    ta_str_t *tas = (ta_str_t *) (item->data);
      72
      73    if( tas->thread_id == thread_id ) {
      74      *list = g_list_remove_link(*list, item);
      75      wr_clear_list( &item );
      76      break;
      77    }
      78  }
      79
      80  return;
      81 }
      82
      83 /* set the activity field */
      84 static
      85 void ta_setactivity_l(ta_str_t *tas, char *activity)
         /* [<][>][^][v][top][bottom][index][help] */
      86 {
      87   char *nl;
      88
      89   strncpy(tas->activity, activity, TA_ACT_LEN-1);
      90   tas->activity[TA_ACT_LEN]=0;
      91   /* convert last newline to a space, if any */
      92   if( (nl=strrchr(tas->activity, '\n')) != NULL ) {
      93     *nl=' ';
      94   }
      95 }
      96
      97
      98 #define TA_HEADER "%-8s %15s %4s %4s %5s %5s %4s %5s %s\n"
      99 #define TA_FORMAT "%-8s %15s %4d %4d %5.1f %5.1f %4d %5.2f %s\n"
     100
     101 static
     102 void ta_print_header(char *buf, int length)
         /* [<][>][^][v][top][bottom][index][help] */
     103 {
     104   snprintf(buf, length, TA_HEADER,
     105            "type", "from", "sock", "thr", "sess", "task", "#",
     106            "avg", "current"
     107            );
     108 }
     109
     110 /* fill in one entry */
     111 static
     112 void ta_printone_l(ta_str_t *tas, char *buf, int length,
         /* [<][>][^][v][top][bottom][index][help] */
     113                    ut_timer_t *reftime)
     114 {
     115   float session, task;  /* duration of the session/task */
     116   char *address = SK_getpeername(tas->sock); /* allocated! */
     117   /* can be NULL for example if the socket has just closed
     118      or the file descriptor is not a socket */
     119
     120   session = UT_timediff( &tas->sessionstart, reftime );
     121   task    = UT_timediff( &tas->taskstart, reftime );
     122
     123   snprintf(buf, length, TA_FORMAT ,
     124            tas->type,
     125            address ? address : "",
     126            tas->sock,
     127            tas->thread_id,
     128            session,
     129            task,
     130            tas->tasks,
     131            (tas->tasks > 0) ? session / tas->tasks : 0,
     132            tas->activity);
     133
     134   if (address) {
     135     wr_free(address);
     136   }
     137 }
     138
     139 /* PUBLIC adding function */
     140 void TA_add(int sock, char *type)
         /* [<][>][^][v][top][bottom][index][help] */
     141 {
     142   ta_str_t *newtas;
     143
     144   /* lock the list */
     145   pthread_mutex_lock( &ta_mutex );
     146
     147   /* find/create node and set peer/thread_id */
     148   newtas = ta_findcreate_l( &ta_list, pthread_self());
     149   newtas->sock = sock;
     150   newtas->tasks = 0;
     151   UT_timeget( &newtas->sessionstart );
     152   UT_timeget( &newtas->taskstart ); /* just to get it a reasonable value */
     153
     154   snprintf(newtas->type, TA_TYPE_LEN, type);
     155   ta_setactivity_l(newtas,"--");
     156
     157   /* unlock */
     158   pthread_mutex_unlock( &ta_mutex );
     159 }
     160
     161
     162 /* PUBLIC deletion function */
     163 void TA_delete(void)
         /* [<][>][^][v][top][bottom][index][help] */
     164 {
     165   /* lock the list */
     166   pthread_mutex_lock( &ta_mutex );
     167
     168   /* find & remove */
     169   ta_remove_l( &ta_list, pthread_self() );
     170
     171   /* unlock */
     172   pthread_mutex_unlock( &ta_mutex );
     173 }
     174
     175
     176 /* PUBLIC activity-setting function */
     177 void TA_setactivity(char *activity)
         /* [<][>][^][v][top][bottom][index][help] */
     178 {
     179   ta_str_t *newtas;
     180
     181   /* lock the list */
     182   pthread_mutex_lock( &ta_mutex );
     183
     184   /* find */
     185   newtas = ta_findcreate_l( &ta_list, pthread_self());
     186
     187   /* set the activity field */
     188   ta_setactivity_l(newtas, activity);
     189
     190   /* unlock */
     191   pthread_mutex_unlock( &ta_mutex );
     192 }
     193
     194 void TA_increment(void)
         /* [<][>][^][v][top][bottom][index][help] */
     195 {
     196   ta_str_t *newtas;
     197
     198   /* lock the list */
     199   pthread_mutex_lock( &ta_mutex );
     200
     201   /* find */
     202   newtas = ta_findcreate_l( &ta_list, pthread_self());
     203   /* increment task */
     204   newtas->tasks++;
     205   /* set task starting time */
     206   UT_timeget( &newtas->taskstart );
     207
     208   /* unlock */
     209   pthread_mutex_unlock( &ta_mutex );
     210 }
     211
     212 char * TA_tostring(void)
         /* [<][>][^][v][top][bottom][index][help] */
     213 {
     214   GList *item;
     215   char *bigbuf = NULL;
     216   char smallbuf[TA_PRINT_LEN];
     217   ut_timer_t reftime;
     218
     219   ta_print_header(smallbuf, TA_PRINT_LEN);
     220   dieif( !NOERR(wr_realloc( (void **) &bigbuf, strlen(smallbuf)+2 )));
     221   strcat(bigbuf, smallbuf);
     222   strcat(bigbuf, "\n");
     223
     224   /* lock the list */
     225   pthread_mutex_lock( &ta_mutex );
     226
     227   /* get reference time */
     228   UT_timeget( &reftime );
     229
     230   /* iterate */
     231   for(item = g_list_first(ta_list);
     232       item != NULL;
     233       item = g_list_next(item)) {
     234     ta_str_t *tas = (ta_str_t *) (item->data);
     235     int smalllen;
     236     int biglen = ( bigbuf == NULL ) ? 0 : strlen(bigbuf);
     237
     238     ta_printone_l(tas, smallbuf, TA_PRINT_LEN, &reftime);
     239     smalllen = strlen(smallbuf);
     240
     241     dieif( !NOERR(wr_realloc( (void **) &bigbuf, biglen+smalllen+3 )));
     242
     243     strcat(bigbuf, smallbuf);
     244   }
     245   /* unlock */
     246   pthread_mutex_unlock( &ta_mutex );
     247
     248   return bigbuf;
     249 }

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