modules/ta/ta.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- ta_findcreate_l
- ta_remove_l
- ta_setactivity_l
- ta_print_header
- ta_printone_l
- TA_add
- TA_delete
- TA_setactivity
- TA_increment
- 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 }