~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/libs/comm/lists/cl_log_list.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <errno.h>
 
3
#include <string.h>
 
4
#include <sys/time.h>
 
5
#include <stdlib.h>
 
6
#include <libgen.h>
 
7
 
 
8
#include "cl_lists.h"
 
9
#include "cl_util.h"
 
10
 
 
11
/*___INFO__MARK_BEGIN__*/
 
12
/*************************************************************************
 
13
 * 
 
14
 *  The Contents of this file are made available subject to the terms of
 
15
 *  the Sun Industry Standards Source License Version 1.2
 
16
 * 
 
17
 *  Sun Microsystems Inc., March, 2001
 
18
 * 
 
19
 * 
 
20
 *  Sun Industry Standards Source License Version 1.2
 
21
 *  =================================================
 
22
 *  The contents of this file are subject to the Sun Industry Standards
 
23
 *  Source License Version 1.2 (the "License"); You may not use this file
 
24
 *  except in compliance with the License. You may obtain a copy of the
 
25
 *  License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
 
26
 * 
 
27
 *  Software provided under this License is provided on an "AS IS" basis,
 
28
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 
29
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 
30
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 
31
 *  See the License for the specific provisions governing your rights and
 
32
 *  obligations concerning the Software.
 
33
 * 
 
34
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
35
 * 
 
36
 *   Copyright: 2001 by Sun Microsystems, Inc.
 
37
 * 
 
38
 *   All Rights Reserved.
 
39
 * 
 
40
 ************************************************************************/
 
41
/*___INFO__MARK_END__*/
 
42
 
 
43
static pthread_mutex_t global_cl_log_list_mutex = PTHREAD_MUTEX_INITIALIZER;
 
44
static cl_raw_list_t* global_cl_log_list = NULL;
 
45
 
 
46
 
 
47
/* this functions must lock / unlock the raw list manually */
 
48
static int cl_log_list_add_log(cl_raw_list_t* list_p, const char* thread_name, int line, const char* function_name, const char* module_name, int thread_id, int thread_state,cl_log_t log_type ,const char* message, const char* parameter ); /* CR check */
 
49
 
 
50
#if 0
 
51
/* this functions are not needed */
 
52
static cl_log_list_elem_t* cl_log_list_get_next_elem(cl_raw_list_t* list_p, cl_log_list_elem_t* elem);
 
53
static cl_log_list_elem_t* cl_log_list_get_last_elem(cl_raw_list_t* list_p, cl_log_list_elem_t* elem);
 
54
#endif
 
55
 
 
56
 
 
57
#ifdef __CL_FUNCTION__
 
58
#undef __CL_FUNCTION__
 
59
#endif
 
60
#define __CL_FUNCTION__ "cl_log_list_add_log()"
 
61
static int cl_log_list_add_log(cl_raw_list_t* list_p, const char* thread_name, int line, const char* function_name, const char* module_name, int thread_id, int thread_state, cl_log_t log_type, const char* message , const char* parameter) { /* CR check */
 
62
   cl_log_list_elem_t* new_elem = NULL;
 
63
   int module_length = 0;
 
64
   char* mod_name_start1 = NULL;  
 
65
   char* mod_name_start = NULL;  
 
66
 
 
67
 
 
68
 
 
69
   if (list_p == NULL || thread_name == NULL || function_name == NULL || module_name == NULL || message == NULL) {
 
70
      return CL_RETVAL_PARAMS;
 
71
   }
 
72
 
 
73
   /* create new cl_log_list_elem_t element */
 
74
   new_elem = (cl_log_list_elem_t*) malloc(sizeof(cl_log_list_elem_t));
 
75
   if (new_elem == NULL) {
 
76
      return CL_RETVAL_MALLOC;
 
77
   }
 
78
 
 
79
   new_elem->log_parameter = NULL;   
 
80
 
 
81
   if (parameter != NULL) {
 
82
      new_elem->log_parameter = strdup(parameter);
 
83
      if (new_elem->log_parameter == NULL) {
 
84
         free(new_elem);
 
85
         return CL_RETVAL_MALLOC;
 
86
      }
 
87
   }
 
88
 
 
89
   new_elem->log_message = strdup(message);    /* malloc */
 
90
   if (new_elem->log_message == NULL) {
 
91
      free(new_elem->log_parameter);
 
92
      free(new_elem);
 
93
      return CL_RETVAL_MALLOC;
 
94
   }
 
95
   
 
96
   new_elem->log_thread_name = strdup(thread_name); /* malloc */
 
97
   if (new_elem->log_thread_name == NULL) {
 
98
      free(new_elem->log_message);
 
99
      free(new_elem->log_parameter);
 
100
      free(new_elem);
 
101
      return CL_RETVAL_MALLOC;
 
102
   }
 
103
 
 
104
   /* this is   b a s e n a m e ( )  */
 
105
   mod_name_start1 = strrchr(module_name,'/');
 
106
   if (mod_name_start1 != NULL) {
 
107
      mod_name_start = mod_name_start1;
 
108
      mod_name_start++;
 
109
   }
 
110
   if (mod_name_start == NULL) {
 
111
      mod_name_start = (char*)module_name;
 
112
   }
 
113
   
 
114
   module_length = strlen(function_name) + strlen(mod_name_start) + cl_util_get_int_number_length(line) + 1 + 4;
 
115
   new_elem->log_module_name = (char*) malloc (sizeof(char) * module_length);
 
116
   if (new_elem->log_module_name == NULL) {
 
117
      free(new_elem->log_message);
 
118
      free(new_elem->log_thread_name);
 
119
      free(new_elem->log_parameter);
 
120
      free(new_elem);
 
121
      return CL_RETVAL_MALLOC;
 
122
   }
 
123
   snprintf(new_elem->log_module_name,module_length, "%s [%s/%d]", function_name, mod_name_start, line );
 
124
 
 
125
   new_elem->log_thread_id = thread_id;
 
126
   new_elem->log_thread_state = thread_state;
 
127
   new_elem->log_type = log_type;
 
128
 
 
129
   /* append elem and set elem pointer in new element */
 
130
   new_elem->raw_elem = cl_raw_list_append_elem(list_p, (void*) new_elem);
 
131
 
 
132
   if ( new_elem->raw_elem == NULL) {
 
133
      free(new_elem->log_message);
 
134
      free(new_elem->log_thread_name);
 
135
      free(new_elem->log_parameter);
 
136
      free(new_elem->log_module_name);
 
137
      free(new_elem);
 
138
      return CL_RETVAL_MALLOC;
 
139
   }
 
140
   return CL_RETVAL_OK;
 
141
}
 
142
 
 
143
 
 
144
#ifdef __CL_FUNCTION__
 
145
#undef __CL_FUNCTION__
 
146
#endif
 
147
#define __CL_FUNCTION__ "cl_log_list_convert_type_id()"
 
148
const char* cl_log_list_convert_type_id(cl_log_t id)  {  /* CR check */
 
149
 
 
150
   switch (id) {
 
151
      case CL_LOG_OFF:
 
152
         return "LOG_OFF";
 
153
      case CL_LOG_ERROR: 
 
154
         return "LOG_ERROR";
 
155
      case CL_LOG_WARNING:
 
156
         return "LOG_WARNING";
 
157
      case CL_LOG_INFO:
 
158
         return "LOG_INFO";
 
159
      case CL_LOG_DEBUG:
 
160
         return "LOG_DEBUG";
 
161
      default:
 
162
         return "undefined";
 
163
   }
 
164
}
 
165
 
 
166
#ifdef __CL_FUNCTION__
 
167
#undef __CL_FUNCTION__
 
168
#endif
 
169
#define __CL_FUNCTION__ "cl_log_list_set_log_level()"
 
170
int cl_log_list_set_log_level(cl_raw_list_t* list_p, cl_log_t new_log_level) {  /* CR check */
 
171
   cl_log_list_data_t* ldata = NULL;
 
172
   cl_log_t log_level = CL_LOG_OFF;
 
173
   char* env_sge_commlib_debug = NULL;
 
174
   if (list_p == NULL) {
 
175
      return CL_RETVAL_PARAMS;
 
176
   }
 
177
 
 
178
   /* check for environment variable SGE_COMMLIB_DEBUG */
 
179
   log_level = new_log_level;
 
180
   env_sge_commlib_debug = getenv("SGE_COMMLIB_DEBUG");
 
181
   if (env_sge_commlib_debug != NULL) {
 
182
      log_level = (cl_log_t) cl_util_get_ulong_value(env_sge_commlib_debug);
 
183
   }
 
184
 
 
185
   if (log_level < CL_LOG_OFF || log_level > CL_LOG_DEBUG) {
 
186
      CL_LOG(CL_LOG_ERROR,"undefined log level");
 
187
      return CL_RETVAL_PARAMS;
 
188
   }
 
189
 
 
190
   ldata = list_p->list_data;
 
191
   if (ldata != NULL) {
 
192
      CL_LOG_STR(CL_LOG_INFO,"setting loglevel to", cl_log_list_convert_type_id(log_level));
 
193
      ldata->current_log_level = log_level;
 
194
      return CL_RETVAL_OK;
 
195
   }
 
196
 
 
197
   return CL_RETVAL_LIST_DATA_IS_NULL;
 
198
}
 
199
 
 
200
#ifdef __CL_FUNCTION__
 
201
#undef __CL_FUNCTION__
 
202
#endif
 
203
#define __CL_FUNCTION__ "cl_log_list_del_log()"
 
204
int cl_log_list_del_log(cl_raw_list_t* list_p) {  /* CR check */
 
205
   cl_log_list_elem_t* elem = NULL;
 
206
   
 
207
   /* search for element */
 
208
   elem = cl_log_list_get_first_elem(list_p);
 
209
 
 
210
   /* remove elem from list and delete elem */
 
211
   if (elem) {
 
212
      cl_raw_list_remove_elem(list_p,elem->raw_elem);
 
213
      free(elem->log_parameter);
 
214
      free(elem->log_message);
 
215
      free(elem->log_thread_name);
 
216
      free(elem->log_module_name);
 
217
      free(elem);
 
218
      return CL_RETVAL_OK;
 
219
   }
 
220
   return CL_RETVAL_THREAD_NOT_FOUND;
 
221
}
 
222
 
 
223
 
 
224
#ifdef __CL_FUNCTION__
 
225
#undef __CL_FUNCTION__
 
226
#endif
 
227
#define __CL_FUNCTION__ "cl_log_list_get_first_elem()"
 
228
cl_log_list_elem_t* cl_log_list_get_first_elem(cl_raw_list_t* list_p) {   /* CR check */
 
229
   cl_raw_list_elem_t* raw_elem = cl_raw_list_get_first_elem(list_p);
 
230
   if (raw_elem) {
 
231
      return (cl_log_list_elem_t*) raw_elem->data;
 
232
   }
 
233
   return NULL;
 
234
}
 
235
 
 
236
#if 0
 
237
#ifdef __CL_FUNCTION__
 
238
#undef __CL_FUNCTION__
 
239
#endif
 
240
#define __CL_FUNCTION__ "cl_log_list_get_next_elem()"
 
241
static cl_log_list_elem_t* cl_log_list_get_next_elem(cl_raw_list_t* list_p, cl_log_list_elem_t* elem) {
 
242
   cl_raw_list_elem_t* next_raw_elem = NULL;
 
243
 
 
244
   if (elem != NULL) {  
 
245
      cl_raw_list_elem_t* raw_elem = elem->raw_elem;
 
246
      next_raw_elem = cl_raw_list_get_next_elem(raw_elem);
 
247
      if (next_raw_elem) {
 
248
         return (cl_log_list_elem_t*) next_raw_elem->data;
 
249
      }
 
250
   }
 
251
   return NULL;
 
252
}
 
253
 
 
254
#ifdef __CL_FUNCTION__
 
255
#undef __CL_FUNCTION__
 
256
#endif
 
257
#define __CL_FUNCTION__ "cl_log_list_get_last_elem()"
 
258
static cl_log_list_elem_t* cl_log_list_get_last_elem(cl_raw_list_t* list_p, cl_log_list_elem_t* elem) {
 
259
   cl_raw_list_elem_t* last_raw_elem = NULL;
 
260
   
 
261
   if (elem != NULL) {
 
262
      cl_raw_list_elem_t* raw_elem = elem->raw_elem;
 
263
      last_raw_elem = cl_raw_list_get_last_elem(raw_elem);
 
264
      if (last_raw_elem) {
 
265
         return (cl_log_list_elem_t*) last_raw_elem->data;
 
266
      }
 
267
   }
 
268
   return NULL;
 
269
}
 
270
#endif
 
271
 
 
272
 
 
273
/* functions from header file */
 
274
 
 
275
 
 
276
 
 
277
/* setup log list 
 
278
 
 
279
   cl_raw_list_t** list_p       -> address to raw list pointer to setup 
 
280
   const char*     creator_name -> name of the creator thread (e.g. "application")
 
281
   int id                       -> creator id
 
282
 
 
283
   return values
 
284
 
 
285
      CL_RETVAL_OK   - list initalized, to cleanup call cl_log_list_cleanup()
 
286
      CL_RETVAL_XXX  - error code   
 
287
 
 
288
   CL_RETVAL_XXX integer
 
289
*/
 
290
#ifdef __CL_FUNCTION__
 
291
#undef __CL_FUNCTION__
 
292
#endif
 
293
#define __CL_FUNCTION__ "cl_log_list_setup()"
 
294
int cl_log_list_setup(cl_raw_list_t** list_p, const char* creator_name, int creator_id, cl_log_list_flush_method_t flush_type, cl_log_func_t flush_func  ) {
 
295
   int ret_val;
 
296
   char* env_sge_commlib_debug = NULL;
 
297
 
 
298
   cl_log_list_data_t* ldata = NULL;
 
299
   cl_thread_settings_t* creator_settings = NULL;
 
300
 
 
301
   if (list_p == NULL || creator_name == NULL) {
 
302
      /* parameter error */
 
303
      return CL_RETVAL_PARAMS;
 
304
   }
 
305
 
 
306
   if (*list_p != NULL) {
 
307
      /* the list is already initialized */
 
308
      return CL_RETVAL_PARAMS;
 
309
   }
 
310
 
 
311
   /* malloc creator and list data structures */
 
312
   creator_settings = (cl_thread_settings_t*)malloc(sizeof(cl_thread_settings_t));
 
313
   if (creator_settings == NULL) {
 
314
      return CL_RETVAL_MALLOC;
 
315
   }
 
316
 
 
317
   ldata = (cl_log_list_data_t*) malloc(sizeof(cl_log_list_data_t));
 
318
   if (ldata == NULL) {
 
319
      free(creator_settings);
 
320
      return CL_RETVAL_MALLOC;
 
321
   }
 
322
   ldata->list_creator_settings = NULL;  /* init the list data to NULL */
 
323
 
 
324
   /* all CL_LOG() macro function calls in startup phase of the log list
 
325
      are lost, because the list is not completey set up !!! */
 
326
 
 
327
   /* create a raw list */
 
328
   ret_val = cl_raw_list_setup(list_p,"log list", 1);/* enable list locking */
 
329
   if (ret_val != CL_RETVAL_OK) {
 
330
      free(creator_settings);
 
331
      free(ldata);
 
332
      return ret_val;
 
333
   }
 
334
 
 
335
   /* set list_data pointer to NULL to disable logging */ 
 
336
   (*list_p)->list_data = NULL;        /* do not log in setup phase */
 
337
   (*list_p)->list_type = CL_LOG_LIST; 
 
338
 
 
339
 
 
340
   /* setup creator thread information */
 
341
   if ( (ret_val=cl_thread_setup(creator_settings,*list_p,creator_name,creator_id , NULL, NULL, NULL)) != CL_RETVAL_OK) {
 
342
      cl_thread_cleanup(creator_settings);
 
343
      free(creator_settings);
 
344
      free(ldata);
 
345
      cl_log_list_cleanup(list_p);
 
346
      return ret_val;
 
347
   }
 
348
 
 
349
   /* initialization done, now set list_data to enable logging */
 
350
   (*list_p)->list_data = ldata;
 
351
   ldata->list_creator_settings = creator_settings;
 
352
   ldata->current_log_level = CL_LOG_WARNING;  /* initial loglevel is CL_LOG_WARNING */
 
353
   ldata->flush_type = flush_type;
 
354
   if (flush_func != NULL) {
 
355
      ldata->flush_function = *flush_func;
 
356
   } else {
 
357
      ldata->flush_function = cl_log_list_flush_list;
 
358
   }
 
359
 
 
360
   /* check for environment variable SGE_COMMLIB_DEBUG */
 
361
   env_sge_commlib_debug=getenv("SGE_COMMLIB_DEBUG");
 
362
   if ( env_sge_commlib_debug != NULL) {
 
363
      ldata->current_log_level = (cl_log_t) cl_util_get_ulong_value(env_sge_commlib_debug);
 
364
   }
 
365
 
 
366
   CL_LOG(CL_LOG_INFO,"cl_log_list_setup() complete");
 
367
 
 
368
   switch(ldata->flush_type) {
 
369
      case CL_LOG_FLUSHED:
 
370
         CL_LOG(CL_LOG_INFO,"log entries are flushed by application");
 
371
         break;
 
372
      case CL_LOG_IMMEDIATE:
 
373
         CL_LOG(CL_LOG_INFO,"log entires are flushed immediate");
 
374
         break;
 
375
   }
 
376
 
 
377
   pthread_mutex_lock(&global_cl_log_list_mutex);
 
378
   global_cl_log_list = *list_p;
 
379
   pthread_mutex_unlock(&global_cl_log_list_mutex);
 
380
 
 
381
   return CL_RETVAL_OK;
 
382
}
 
383
 
 
384
 
 
385
#ifdef __CL_FUNCTION__
 
386
#undef __CL_FUNCTION__
 
387
#endif
 
388
#define __CL_FUNCTION__ "cl_log_list_cleanup()"
 
389
int cl_log_list_cleanup(cl_raw_list_t** list_p ) {          /* CR check */
 
390
   int ret_val;
 
391
   int ret_val2;
 
392
   cl_log_list_data_t* ldata = NULL;
 
393
   cl_thread_settings_t* creator_settings = NULL;
 
394
 
 
395
   if (list_p == NULL) {
 
396
      return CL_RETVAL_PARAMS;
 
397
   }
 
398
   if (*list_p == NULL) {
 
399
      return CL_RETVAL_PARAMS;
 
400
   }
 
401
 
 
402
   pthread_mutex_lock(&global_cl_log_list_mutex);
 
403
   global_cl_log_list = NULL;
 
404
   pthread_mutex_unlock(&global_cl_log_list_mutex);
 
405
 
 
406
   /* set ldata and creator_settings */
 
407
   ldata = (cl_log_list_data_t*)   (*list_p)->list_data;
 
408
   if (ldata != NULL) {
 
409
      creator_settings = ldata->list_creator_settings;
 
410
   }
 
411
 
 
412
   /* cleanup creator thread */
 
413
   ret_val = cl_thread_cleanup(creator_settings); 
 
414
 
 
415
   /* flush all list content to get list empty*/
 
416
   cl_log_list_flush_list(*list_p ); 
 
417
 
 
418
   /* free list data */
 
419
   free(ldata);
 
420
   (*list_p)->list_data = NULL; 
 
421
 
 
422
   /* free creator_settings */ 
 
423
   free(creator_settings);
 
424
 
 
425
   ret_val2 = cl_raw_list_cleanup(list_p);
 
426
 
 
427
   if (ret_val != CL_RETVAL_OK) {
 
428
      return ret_val;
 
429
   }
 
430
   return ret_val2;
 
431
}
 
432
 
 
433
#if 0
 
434
 
 
435
#ifdef __CL_FUNCTION__
 
436
#undef __CL_FUNCTION__
 
437
#endif
 
438
#define __CL_FUNCTION__ "cl_log_list_get_creator_thread()"
 
439
cl_thread_settings_t* cl_log_list_get_creator_thread(cl_thread_settings_t* thread_config) {  /* CR check */
 
440
   cl_raw_list_t*         log_list = NULL;
 
441
   cl_thread_settings_t*  creator_thread = NULL;
 
442
   cl_log_list_data_t*    ldata = NULL;
 
443
 
 
444
   if (thread_config == NULL) {
 
445
      return NULL;
 
446
   }
 
447
 
 
448
   log_list = thread_config->thread_log_list;   
 
449
   if (log_list != NULL) {
 
450
      ldata = log_list->list_data;
 
451
      if (ldata != NULL) {
 
452
         creator_thread = ldata->list_creator_settings;
 
453
      }
 
454
   }
 
455
   return creator_thread;
 
456
}
 
457
#endif
 
458
 
 
459
#ifdef __CL_FUNCTION__
 
460
#undef __CL_FUNCTION__
 
461
#endif
 
462
#define __CL_FUNCTION__ "cl_log_list_log()"
 
463
int cl_log_list_log(cl_log_t log_type,int line, const char* function_name,const char* module_name, const char* log_text, const char* log_param) {
 
464
 
 
465
   int ret_val;
 
466
   int ret_val2;
 
467
   cl_thread_settings_t* thread_config = NULL;
 
468
   cl_log_list_data_t*   ldata = NULL;
 
469
 
 
470
   if (log_text == NULL || module_name == NULL || function_name == NULL) {
 
471
      return CL_RETVAL_PARAMS;
 
472
   }
 
473
 
 
474
   /* get the thread configuration for the calling thread */
 
475
   thread_config = cl_thread_get_thread_config();
 
476
  
 
477
#if 0
 
478
   /* This is to get all debug messages at startup of log list, only enable this
 
479
      for debugging the log list code */
 
480
   if (thread_config == NULL) {
 
481
      printf("cl_log_list_log(): cl_thread_get_thread_config() returns NULL\n");
 
482
      if (log_text && module_name && log_param) { printf("%s:%s %s\n",function_name , log_text, log_param);}
 
483
   }
 
484
#endif
 
485
 
 
486
 
 
487
   if (thread_config != NULL) {
 
488
      if (thread_config->thread_log_list == NULL) {
 
489
         return CL_RETVAL_LOG_NO_LOGLIST;
 
490
      }
 
491
   
 
492
   
 
493
      /* check current log level */
 
494
      ldata = thread_config->thread_log_list->list_data;
 
495
      if (ldata != NULL) {
 
496
         if (ldata->current_log_level < log_type || ldata->current_log_level == CL_LOG_OFF) {
 
497
            return CL_RETVAL_OK;  /* message log doesn't match current log level or is switched off */
 
498
         }
 
499
      } else {
 
500
         return CL_RETVAL_OK;  /* never try logging without list data ( this happens on setting up the log list ) */
 
501
      }
 
502
   
 
503
      if (  ( ret_val = cl_raw_list_lock(thread_config->thread_log_list)) != CL_RETVAL_OK) {
 
504
         return ret_val;
 
505
      }
 
506
   
 
507
      ret_val2 = cl_log_list_add_log( thread_config->thread_log_list,
 
508
                                      thread_config->thread_name,
 
509
                                      line, 
 
510
                                      function_name, 
 
511
                                      module_name,
 
512
                                      thread_config->thread_id,
 
513
                                      thread_config->thread_state,
 
514
                                      log_type, 
 
515
                                      log_text, 
 
516
                                      log_param ); 
 
517
      
 
518
      if (  ( ret_val = cl_raw_list_unlock(thread_config->thread_log_list)) != CL_RETVAL_OK) {
 
519
         return ret_val;
 
520
      }
 
521
      if (ldata != NULL) {
 
522
         if(ldata->flush_type == CL_LOG_IMMEDIATE) {
 
523
            cl_log_list_flush();
 
524
         }
 
525
      }
 
526
      return ret_val2;
 
527
   } else {
 
528
      /* TODO 2 of 2 :
 
529
       *  This happens to threads of application which have not started 
 
530
       *  commlib setup function. A thread config should be provided for these
 
531
       *  threads, or the application should use commlib threads ( lists/thread module ) 
 
532
       */
 
533
      pthread_mutex_lock(&global_cl_log_list_mutex);
 
534
      /* This must be an application thread */
 
535
      if ( global_cl_log_list != NULL) {
 
536
         ldata = global_cl_log_list->list_data;
 
537
         if (ldata != NULL) {
 
538
            if (ldata->current_log_level < log_type || ldata->current_log_level == CL_LOG_OFF) {
 
539
               pthread_mutex_unlock(&global_cl_log_list_mutex);
 
540
               return CL_RETVAL_OK;  /* message log doesn't match current log level or is switched off */
 
541
            }
 
542
         } else {
 
543
            pthread_mutex_unlock(&global_cl_log_list_mutex);
 
544
            return CL_RETVAL_OK;  /* never try logging without list data ( this happens on setting up the log list ) */
 
545
         }
 
546
         if (  ( ret_val = cl_raw_list_lock(global_cl_log_list)) != CL_RETVAL_OK) {
 
547
            pthread_mutex_unlock(&global_cl_log_list_mutex);
 
548
            return ret_val;
 
549
         }
 
550
 
 
551
         ret_val2 = cl_log_list_add_log( global_cl_log_list,
 
552
                                         "unknown thread",
 
553
                                         line, 
 
554
                                         function_name, 
 
555
                                         module_name,
 
556
                                         -1,
 
557
                                         -1,
 
558
                                          log_type, 
 
559
                                          log_text, 
 
560
                                          log_param ); 
 
561
 
 
562
         if (  ( ret_val = cl_raw_list_unlock(global_cl_log_list)) != CL_RETVAL_OK) {
 
563
            pthread_mutex_unlock(&global_cl_log_list_mutex);
 
564
            return ret_val;
 
565
         }
 
566
         if (ldata != NULL) {
 
567
            if(ldata->flush_type == CL_LOG_IMMEDIATE) {
 
568
               cl_log_list_flush();
 
569
            }
 
570
         }
 
571
         pthread_mutex_unlock(&global_cl_log_list_mutex);
 
572
         return ret_val2;
 
573
      }
 
574
      pthread_mutex_unlock(&global_cl_log_list_mutex);
 
575
      return CL_RETVAL_LOG_NO_LOGLIST;
 
576
   }
 
577
}
 
578
 
 
579
#ifdef __CL_FUNCTION__
 
580
#undef __CL_FUNCTION__
 
581
#endif
 
582
#define __CL_FUNCTION__ "cl_log_list_log_ssi()"
 
583
int cl_log_list_log_ssi(cl_log_t log_type,int line, const char* function_name,const char* module_name, const char* log_text,
 
584
                        const char* log_1 , const char* log_2 ,int log_3 ) {
 
585
   int ret_val;
 
586
   char my_buffer[512];
 
587
   cl_thread_settings_t* thread_config = NULL;
 
588
   cl_log_list_data_t*   ldata = NULL;
 
589
   const char* help_null = "NULL";
 
590
   const char* log_param1 = NULL;
 
591
   const char* log_param2 = NULL;
 
592
 
 
593
   /* get the thread configuration for the calling thread */
 
594
   thread_config = cl_thread_get_thread_config();
 
595
   if (thread_config != NULL) {
 
596
      if (thread_config->thread_log_list == NULL) {
 
597
         return CL_RETVAL_LOG_NO_LOGLIST;
 
598
      } 
 
599
      ldata = thread_config->thread_log_list->list_data;
 
600
   } else {
 
601
      /* TODO 1 of 2 :
 
602
       *  This happens to threads of application which have not started 
 
603
       *  commlib setup function. A thread config should be provided for these
 
604
       *  threads, or the application should use commlib threads ( lists/thread module ) 
 
605
       */
 
606
       pthread_mutex_lock(&global_cl_log_list_mutex);
 
607
       if ( global_cl_log_list != NULL) {
 
608
          ldata = global_cl_log_list->list_data;
 
609
       }
 
610
       pthread_mutex_unlock(&global_cl_log_list_mutex);
 
611
   }
 
612
 
 
613
   if (ldata != NULL) {
 
614
      if (ldata->current_log_level < log_type || ldata->current_log_level == CL_LOG_OFF) {
 
615
         return CL_RETVAL_OK;  /* message log doesn't match current log level or is switched off */
 
616
      }
 
617
   } else {
 
618
      return CL_RETVAL_OK;  /* never try logging without list data ( this happens on setting up the log list ) */
 
619
   }   
 
620
   if (log_1 == NULL) {
 
621
      log_param1 = help_null;
 
622
   } else {
 
623
      log_param1 = log_1;
 
624
   }
 
625
 
 
626
   if (log_2 == NULL) {
 
627
      log_param2 = help_null;
 
628
   } else {
 
629
      log_param2 = log_2;
 
630
   }
 
631
   snprintf(my_buffer, 512, "\"%s/%s/%d\"", log_param1, log_param2, log_3);
 
632
   ret_val = cl_log_list_log( log_type, line,  function_name, module_name,  log_text,  my_buffer);
 
633
   return ret_val;
 
634
}
 
635
 
 
636
 
 
637
#ifdef __CL_FUNCTION__
 
638
#undef __CL_FUNCTION__
 
639
#endif
 
640
#define __CL_FUNCTION__ "cl_log_list_log_int()"
 
641
int cl_log_list_log_int(cl_log_t log_type,int line, const char* function_name,const char* module_name, const char* log_text, int param) {
 
642
   int ret_val;
 
643
   char my_int_buffer[512];
 
644
   cl_thread_settings_t* thread_config = NULL;
 
645
   cl_log_list_data_t*   ldata = NULL;
 
646
 
 
647
   /* get the thread configuration for the calling thread */
 
648
   thread_config = cl_thread_get_thread_config();
 
649
   if (thread_config != NULL) {
 
650
      if (thread_config->thread_log_list == NULL) {
 
651
         return CL_RETVAL_LOG_NO_LOGLIST;
 
652
      } 
 
653
      ldata = thread_config->thread_log_list->list_data;
 
654
   } else {
 
655
      /* TODO 1 of 2 :
 
656
       *  This happens to threads of application which have not started 
 
657
       *  commlib setup function. A thread config should be provided for these
 
658
       *  threads, or the application should use commlib threads ( lists/thread module ) 
 
659
       */
 
660
       pthread_mutex_lock(&global_cl_log_list_mutex);
 
661
       if ( global_cl_log_list != NULL) {
 
662
          ldata = global_cl_log_list->list_data;
 
663
       }
 
664
       pthread_mutex_unlock(&global_cl_log_list_mutex);
 
665
   }
 
666
 
 
667
   if (ldata != NULL) {
 
668
      if (ldata->current_log_level < log_type || ldata->current_log_level == CL_LOG_OFF) {
 
669
         return CL_RETVAL_OK;  /* message log doesn't match current log level or is switched off */
 
670
      }
 
671
   } else {
 
672
      return CL_RETVAL_OK;  /* never try logging without list data ( this happens on setting up the log list ) */
 
673
   }   
 
674
 
 
675
   snprintf(my_int_buffer, 512, "%d", param);
 
676
   ret_val = cl_log_list_log( log_type, line,  function_name, module_name,  log_text,  my_int_buffer);
 
677
   return ret_val;
 
678
}
 
679
 
 
680
 
 
681
#ifdef __CL_FUNCTION__
 
682
#undef __CL_FUNCTION__
 
683
#endif
 
684
#define __CL_FUNCTION__ "cl_log_list_flush()"
 
685
int cl_log_list_flush(void) {        /* CR check */
 
686
   cl_raw_list_t* list_p = NULL;
 
687
   cl_thread_settings_t* thread_config = NULL;
 
688
   cl_log_list_data_t* ldata = NULL;  
 
689
   
 
690
   /* get the thread configuration for the calling thread */
 
691
   thread_config = cl_thread_get_thread_config();
 
692
   if (thread_config == NULL) {
 
693
      /* This thread has had no setup by commlib, it must be an
 
694
       * application thread
 
695
       */
 
696
      list_p = global_cl_log_list;
 
697
   } else {
 
698
      /* This is a commlib internal thread use thread config */
 
699
      list_p = thread_config->thread_log_list;
 
700
   }
 
701
 
 
702
   if (list_p == NULL) {
 
703
      return CL_RETVAL_LOG_NO_LOGLIST;
 
704
   }
 
705
 
 
706
   /* here we have a log list pointer, check if
 
707
    * there is a log function definition */
 
708
   if (list_p->list_data != NULL) {
 
709
      ldata = (cl_log_list_data_t*)list_p->list_data;
 
710
      if (ldata->flush_function != NULL) {
 
711
         return ldata->flush_function(list_p);
 
712
      }
 
713
   }
 
714
   return cl_log_list_flush_list(list_p);
 
715
}
 
716
   
 
717
 
 
718
 
 
719
#ifdef __CL_FUNCTION__
 
720
#undef __CL_FUNCTION__
 
721
#endif
 
722
#define __CL_FUNCTION__ "cl_log_list_flush_list()"
 
723
int cl_log_list_flush_list(cl_raw_list_t* list_p) {        /* CR check */
 
724
   int ret_val;
 
725
   cl_log_list_elem_t* elem = NULL;
 
726
   struct timeval now;
 
727
 
 
728
   
 
729
   if (list_p == NULL) {
 
730
      return CL_RETVAL_LOG_NO_LOGLIST;
 
731
   }
 
732
 
 
733
   if (  ( ret_val = cl_raw_list_lock(list_p)) != CL_RETVAL_OK) {
 
734
      return ret_val;
 
735
   }
 
736
 
 
737
   while ( (elem = cl_log_list_get_first_elem(list_p) ) != NULL) {
 
738
      /* TODO: rework logging output (log to file? call foreign log function, got by function pointer ?) */
 
739
 
 
740
      gettimeofday(&now,NULL);
 
741
 
 
742
      printf("%-76s|", elem->log_module_name);
 
743
      if (elem->log_parameter == NULL) {
 
744
#define CL_COM_PRINT_THREAD_ID 0
 
745
 
 
746
#if CL_COM_PRINT_THREAD_ID
 
747
         printf("%ld.%ld|%20s|%4d|%10s|%8s| %s\n",
 
748
#else
 
749
         printf("%ld.%ld|%20s|%10s|%8s| %s\n",
 
750
#endif
 
751
 
 
752
         (long)now.tv_sec,
 
753
         (long)now.tv_usec,
 
754
         elem->log_thread_name,
 
755
#if CL_COM_PRINT_THREAD_ID
 
756
         elem->log_thread_id, 
 
757
#endif
 
758
         cl_thread_convert_state_id(elem->log_thread_state),
 
759
         cl_log_list_convert_type_id(elem->log_type),
 
760
         elem->log_message);
 
761
      } else {
 
762
#if CL_COM_PRINT_THREAD_ID
 
763
         printf("%ld.%ld|%20s|%4d|%10s|%8s| %s %s\n",
 
764
#else
 
765
         printf("%ld.%ld|%20s|%10s|%8s| %s %s\n",
 
766
#endif
 
767
 
 
768
         (long)now.tv_sec,
 
769
         (long)now.tv_usec,
 
770
         elem->log_thread_name,
 
771
#if CL_COM_PRINT_THREAD_ID
 
772
         elem->log_thread_id, 
 
773
#endif
 
774
         cl_thread_convert_state_id(elem->log_thread_state),
 
775
         cl_log_list_convert_type_id(elem->log_type),
 
776
         elem->log_message,
 
777
         elem->log_parameter);
 
778
      }
 
779
      cl_log_list_del_log(list_p);
 
780
      fflush(stdout);
 
781
   }
 
782
   
 
783
   if (  ( ret_val = cl_raw_list_unlock(list_p)) != CL_RETVAL_OK) {
 
784
      return ret_val;
 
785
   } 
 
786
   return CL_RETVAL_OK;
 
787
}
 
788
 
 
789
 
 
790
 
 
791
 
 
792
 
 
793