Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,1157 +0,0 @@
1
-/*
2
- * Copyright (C) 2001-2003 FhG Fokus
3
- *
4
- * This file is part of Kamailio, a free SIP server.
5
- *
6
- * Kamailio is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * Kamailio is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
- */
20
-
21
-/**
22
- * @file
23
- * @brief Kamailio core :: Timer
24
- * @ingroup core
25
- * Module: @ref core
26
- */
27
-
28
-#include "timer.h"
29
-#include "timer_funcs.h"
30
-#include "timer_ticks.h"
31
-#include "dprint.h"
32
-#include <time.h>     /* gettimeofday */
33
-#include <sys/time.h> /* setitimer, gettimeofday */
34
-#include <signal.h>   /* SIGALRM */
35
-#include <errno.h>
36
-#include <unistd.h> /* pause() */
37
-#include <stdlib.h> /* random, debugging only */
38
-#include "error.h"
39
-#include "signals.h"
40
-
41
-/*
42
-#include "config.h"
43
-*/
44
-#include "globals.h"
45
-#include "mem/mem.h"
46
-#ifdef SHM_MEM
47
-#include "mem/shm_mem.h"
48
-#endif
49
-#include "locking.h"
50
-#include "sched_yield.h"
51
-#include "cfg/cfg_struct.h"
52
-
53
-
54
-/* how often will the timer handler be called (in ticks) */
55
-#define TIMER_HANDLER_INTERVAL	1U
56
-/* how often to try to re-adjust the ticks */
57
-#define TIMER_RESYNC_TICKS	(TIMER_TICKS_HZ*5U)  /* each 5 s */
58
-#define TIMER_MAX_DRIFT	(TIMER_TICKS_HZ/10U) /* if drift > 0.1s adjust */
59
-
60
-
61
-
62
-static ticks_t* ticks=0;
63
-static ticks_t last_ticks; /* last time we adjusted the time */
64
-static ticks_t last_adj_check; /* last time we ran adjust_ticks */
65
-static ticks_t prev_ticks; /* last time we ran the timer, also used as
66
-							*  "current" ticks when running the timer for
67
-							*  "skipped" ticks */
68
-
69
-static struct timeval last_time;
70
-static struct timeval start_time; /* for debugging */
71
-
72
-static volatile int run_timer=0;
73
-static int timer_id=0;
74
-
75
-static gen_lock_t* timer_lock=0;
76
-static struct timer_ln* volatile* running_timer=0;/* running timer handler */
77
-static int in_timer=0;
78
-
79
-#define IS_IN_TIMER() (in_timer)
80
-
81
-#define LOCK_TIMER_LIST()		lock_get(timer_lock)
82
-#define UNLOCK_TIMER_LIST()		lock_release(timer_lock)
83
-
84
-/* we can get away without atomic_set/atomic_cmp and write barriers because we
85
- * always call SET_RUNNING and IS_RUNNING while holding the timer lock
86
- * => it's implicitly atomic and the lock acts as write barrier */
87
-#define SET_RUNNING(t)		(*running_timer=(t))
88
-#define IS_RUNNING(t)		(*running_timer==(t))
89
-#define UNSET_RUNNING()		(*running_timer=0)
90
-
91
-#ifdef USE_SLOW_TIMER
92
-
93
-#define SLOW_TIMER_SIG	SIGUSR2
94
-/* timer flags checks */
95
-#define IS_FAST_TIMER(t)	(t->flags&F_TIMER_FAST)
96
-#define SET_SLOW_LIST(t)	(t->flags|=F_TIMER_ON_SLOW_LIST)
97
-#define RESET_SLOW_LIST(t)	(t->flags&=~F_TIMER_ON_SLOW_LIST)
98
-#define IS_ON_SLOW_LIST(t)	(t->flags&F_TIMER_ON_SLOW_LIST)
99
-
100
-#define SLOW_LISTS_NO	1024U  /* slow lists number, 2^k recommended */
101
-
102
-
103
-static gen_lock_t*  slow_timer_lock; /* slow timer lock */
104
-static struct timer_head* slow_timer_lists;
105
-static volatile unsigned short* t_idx; /* "main" timer index in slow_lists[] */
106
-static volatile unsigned short* s_idx; /* "slow" timer index in slow_lists[] */
107
-static struct timer_ln* volatile* running_timer2=0; /* timer handler running
108
-													 * in the "slow" timer */
109
-static sigset_t slow_timer_sset;
110
-pid_t slow_timer_pid;
111
-static int in_slow_timer=0;
112
-
113
-#define IS_IN_TIMER_SLOW() (in_slow_timer)
114
-#define SET_RUNNING_SLOW(t)		(*running_timer2=(t))
115
-#define IS_RUNNING_SLOW(t)		(*running_timer2==(t))
116
-#define UNSET_RUNNING_SLOW()	(*running_timer2=0)
117
-
118
-#define LOCK_SLOW_TIMER_LIST()		lock_get(slow_timer_lock)
119
-#define UNLOCK_SLOW_TIMER_LIST()	lock_release(slow_timer_lock)
120
-
121
-
122
-#endif
123
-
124
-
125
-struct timer_lists* timer_lst=0;
126
-
127
-void sig_timer(int signo)
128
-{
129
-	(*ticks)++;
130
-	if (( *ticks % TIMER_HANDLER_INTERVAL)==0){
131
-		/* set a flag to run the handler */
132
-		run_timer=1;
133
-	}
134
-}
135
-
136
-
137
-
138
-void destroy_timer()
139
-{
140
-	struct itimerval it;
141
-
142
-	/* disable timer */
143
-	memset(&it, 0, sizeof(it));
144
-	setitimer(ITIMER_REAL, &it, 0);
145
-	set_sig_h(SIGALRM, SIG_IGN);
146
-	if (timer_lock){
147
-		lock_destroy(timer_lock);
148
-		lock_dealloc(timer_lock);
149
-		timer_lock=0;
150
-	}
151
-	if (ticks){
152
-#ifdef SHM_MEM
153
-		shm_free(ticks);
154
-#else
155
-		pkg_free(ticks);
156
-#endif
157
-		ticks=0;
158
-	}
159
-	if (timer_lst){
160
-#ifdef SHM_MEM
161
-		shm_free(timer_lst);
162
-#else
163
-		pkg_free(timer_lst);
164
-#endif
165
-		timer_lst=0;
166
-	}
167
-	if (running_timer){
168
-		shm_free((void*)running_timer);
169
-		running_timer=0;
170
-	}
171
-#ifdef USE_SLOW_TIMER
172
-	if (slow_timer_lock){
173
-		lock_destroy(slow_timer_lock);
174
-		lock_dealloc(slow_timer_lock);
175
-		slow_timer_lock=0;
176
-	}
177
-	if (slow_timer_lists){
178
-		shm_free((void*)slow_timer_lists);
179
-		slow_timer_lists=0;
180
-	}
181
-	if (t_idx){
182
-		shm_free((void*)t_idx);
183
-		t_idx=0;
184
-	}
185
-	if (s_idx){
186
-		shm_free((void*)s_idx);
187
-		s_idx=0;
188
-	}
189
-	if(running_timer2){
190
-		shm_free((void*)running_timer2);
191
-		running_timer2=0;
192
-	}
193
-#endif
194
-}
195
-
196
-
197
-
198
-/* ret 0 on success, <0 on error*/
199
-int init_timer()
200
-{
201
-	int r;
202
-	int ret;
203
-
204
-	ret=-1;
205
-
206
-	/* init the locks */
207
-	timer_lock=lock_alloc();
208
-	if (timer_lock==0){
209
-		ret=E_OUT_OF_MEM;
210
-		goto error;
211
-	}
212
-	if (lock_init(timer_lock)==0){
213
-		lock_dealloc(timer_lock);
214
-		timer_lock=0;
215
-		ret=-1;
216
-		goto error;
217
-	}
218
-	/* init the shared structs */
219
-#ifdef SHM_MEM
220
-	ticks=shm_malloc(sizeof(ticks_t));
221
-	timer_lst=shm_malloc(sizeof(struct timer_lists));
222
-#else
223
-	/* in this case get_ticks won't work! */
224
-	LM_WARN("no shared memory support compiled in get_ticks won't work\n");
225
-	ticks=pkg_malloc(sizeof(ticks_t));
226
-	timer_lst=pkg_malloc(sizeof(struct timer_lists));
227
-#endif
228
-	if (ticks==0){
229
-		LM_CRIT("out of shared memory (ticks)\n");
230
-		ret=E_OUT_OF_MEM;
231
-		goto error;
232
-	}
233
-	if (timer_lst==0){
234
-		LM_CRIT("out of shared memory (timer_lst)\n");
235
-		ret=E_OUT_OF_MEM;
236
-		goto error;
237
-	}
238
-	running_timer=shm_malloc(sizeof(struct timer_ln*));
239
-	if (running_timer==0){
240
-		LM_CRIT("out of memory (running_timer)\n");
241
-		ret=E_OUT_OF_MEM;
242
-		goto error;
243
-	}
244
-
245
-	/* initial values */
246
-	memset(timer_lst, 0, sizeof(struct timer_lists));
247
-	*ticks=random(); /* random value for start, for debugging */
248
-	prev_ticks=last_ticks=last_adj_check=*ticks;
249
-	*running_timer=0;
250
-	if (gettimeofday(&start_time, 0)<0){
251
-		LM_ERR("gettimeofday failed: %s [%d]\n", strerror(errno), errno);
252
-		ret=-1;
253
-		goto error;
254
-	}
255
-	last_time=start_time;
256
-	LM_DBG("starting with *ticks=%u\n", (unsigned) *ticks);
257
-
258
-	/* init timer structures */
259
-	for (r=0; r<H0_ENTRIES; r++)
260
-		_timer_init_list(&timer_lst->h0[r]);
261
-	for (r=0; r<H1_ENTRIES; r++)
262
-		_timer_init_list(&timer_lst->h1[r]);
263
-	for (r=0; r<H2_ENTRIES; r++)
264
-		_timer_init_list(&timer_lst->h2[r]);
265
-	_timer_init_list(&timer_lst->expired);
266
-
267
-#ifdef USE_SLOW_TIMER
268
-
269
-	/* init the locks */
270
-	slow_timer_lock=lock_alloc();
271
-	if (slow_timer_lock==0){
272
-		ret=E_OUT_OF_MEM;
273
-		goto error;
274
-	}
275
-	if (lock_init(slow_timer_lock)==0){
276
-		lock_dealloc(slow_timer_lock);
277
-		slow_timer_lock=0;
278
-		ret=-1;
279
-		goto error;
280
-	}
281
-	t_idx=shm_malloc(sizeof(*t_idx));
282
-	s_idx=shm_malloc(sizeof(*s_idx));
283
-	slow_timer_lists=shm_malloc(sizeof(struct timer_head)*SLOW_LISTS_NO);
284
-	running_timer2=shm_malloc(sizeof(struct timer_ln*));
285
-	if ((t_idx==0)||(s_idx==0) || (slow_timer_lists==0) ||(running_timer2==0)){
286
-		LM_ERR("out of shared memory (slow)\n");
287
-		ret=E_OUT_OF_MEM;
288
-		goto error;
289
-	}
290
-	*t_idx=*s_idx=0;
291
-	*running_timer2=0;
292
-	for (r=0; r<SLOW_LISTS_NO; r++)
293
-		_timer_init_list(&slow_timer_lists[r]);
294
-
295
-#endif
296
-
297
-	LM_DBG("timer_list between %p and %p\n",
298
-			&timer_lst->h0[0], &timer_lst->h2[H2_ENTRIES]);
299
-	return 0;
300
-error:
301
-	destroy_timer();
302
-	return ret;
303
-}
304
-
305
-
306
-
307
-#ifdef USE_SLOW_TIMER
308
-/* arm the "slow" timer ( start it)
309
- * returns -1 on error
310
- * WARNING: use it in the same process as the timer
311
- *  (the one using pause(); timer_handler()) or
312
- *  change run_timer to a pointer in shared mem */
313
-int arm_slow_timer()
314
-{
315
-	sigemptyset(&slow_timer_sset);
316
-	sigaddset(&slow_timer_sset, SLOW_TIMER_SIG);
317
-again:
318
-	if (sigprocmask(SIG_BLOCK, &slow_timer_sset, 0)==-1){
319
-		if (errno==EINTR) goto again;
320
-		LM_ERR("sigprocmask failed: %s [%d]}n", strerror(errno), errno);
321
-		goto error;
322
-	}
323
-#ifdef __OS_darwin
324
-	/* workaround for darwin sigwait bug, see slow_timer_main() for more
325
-	 * info (or grep __OS_darwin) */
326
-	/* keep in sync wih main.c: sig_usr() - signals we are interested in */
327
-	sigaddset(&slow_timer_sset, SIGINT);
328
-	sigaddset(&slow_timer_sset, SIGTERM);
329
-	sigaddset(&slow_timer_sset, SIGUSR1);
330
-	sigaddset(&slow_timer_sset, SIGHUP);
331
-	sigaddset(&slow_timer_sset, SIGCHLD);
332
-	sigaddset(&slow_timer_sset, SIGALRM);
333
-#endif
334
-	/* initialize the config framework */
335
-	if (cfg_child_init()) goto error;
336
-
337
-	return 0;
338
-error:
339
-	return -1;
340
-}
341
-#endif
342
-
343
-
344
-
345
-
346
-/* arm the timer ( start it)
347
- * returns -1 on error
348
- * WARNING: use it in the same process as the timer
349
- *  (the one using pause(); timer_handler()) or
350
- *  change run_timer to a pointer in shared mem */
351
-int arm_timer()
352
-{
353
-	struct itimerval it;
354
-	/* init signal generation */
355
-	it.it_interval.tv_sec=0;
356
-	it.it_interval.tv_usec=1000000/TIMER_TICKS_HZ;
357
-	it.it_value=it.it_interval;
358
-	/* install the signal handler */
359
-	if (set_sig_h(SIGALRM, sig_timer) == SIG_ERR ){
360
-		LM_CRIT("SIGALRM signal handler cannot be installed: %s [%d]\n",
361
-					strerror(errno), errno);
362
-		return -1;
363
-	}
364
-	if (setitimer(ITIMER_REAL, &it, 0) == -1){
365
-		LM_CRIT("setitimer failed: %s [%d]\n", strerror(errno), errno);
366
-		return -1;
367
-	}
368
-	if (gettimeofday(&last_time, 0)<0){
369
-		LM_ERR("gettimeofday failed: %s [%d]\n", strerror(errno), errno);
370
-		return -1;
371
-	}
372
-	/* initialize the config framework */
373
-	if (cfg_child_init()) return -1;
374
-
375
-	return 0;
376
-}
377
-
378
-
379
-
380
-#ifdef DBG_ser_time
381
-/* debugging  only */
382
-void check_ser_drift();
383
-#endif /* DBG_set_time */
384
-
385
-
386
-
387
-/* adjust the timer using the "real" time, each TIMER_RESYNC_TICKS, but only
388
- * if timer drift > TIMER_MAX_DRIFT
389
- * NOTES: - it will adjust time within  TIMER_MAX_DRIFT from the "real"
390
- *          elapsed time
391
- *        - it will never decrease the *ticks, only increase it (monotonic)
392
- *        - it works ok as long as the adjustment interval < MAX_TICKS_T
393
- * -- andrei
394
- */
395
-inline static void adjust_ticks(void)
396
-{
397
-	struct timeval crt_time;
398
-	long long diff_time;
399
-	ticks_t diff_time_ticks;
400
-	ticks_t diff_ticks_raw;
401
-	s_ticks_t delta;
402
-
403
-	/* fix ticks if necessary */
404
-	if ((*ticks-last_adj_check)>=(ticks_t)TIMER_RESYNC_TICKS){
405
-#ifdef DBG_ser_time
406
-		check_ser_drift();
407
-#endif /* DBG_ser_time */
408
-		last_adj_check=*ticks;
409
-		if (gettimeofday(&crt_time, 0)<0){
410
-			LM_ERR("gettimeofday failed: %s [%d]\n", strerror(errno), errno);
411
-			return; /* ignore */
412
-		}
413
-		diff_time=(long long)crt_time.tv_sec*1000000+crt_time.tv_usec-
414
-					((long long) last_time.tv_sec*1000000+last_time.tv_usec);
415
-		if (diff_time<0){
416
-			LM_WARN("time changed backwards %ld ms ignoring...\n",
417
-						(long)(diff_time/1000));
418
-			last_time=crt_time;
419
-			last_ticks=*ticks;
420
-		}else{
421
-			diff_ticks_raw=*ticks-last_ticks;
422
-			diff_time_ticks=(ticks_t)((diff_time*TIMER_TICKS_HZ)/1000000LL);
423
-			delta=(s_ticks_t)(diff_time_ticks-diff_ticks_raw);
424
-			if (delta<-1){
425
-				LM_WARN("our timer runs faster then real-time"
426
-						" (%lu ms / %u ticks our time .->"
427
-						" %lu ms / %u ticks real time)\n",
428
-						(unsigned long)(diff_ticks_raw*1000L/TIMER_TICKS_HZ),
429
-						diff_ticks_raw,
430
-						(unsigned long)(diff_time/1000), diff_time_ticks);
431
-				last_time=crt_time;
432
-				last_ticks=*ticks;
433
-			}else{
434
-				/* fix the ticks */
435
-				if (delta>(s_ticks_t)TIMER_MAX_DRIFT){
436
-#ifndef TIMER_DEBUG
437
-					if (delta > 2*(s_ticks_t)TIMER_MAX_DRIFT+1)
438
-#endif
439
-						LM_DBG("adjusting timer ticks (%lu) with %ld ms"
440
-								" (%ld ticks)\n",
441
-								(unsigned long)*ticks,
442
-							(long)(delta*1000)/TIMER_TICKS_HZ, (long)delta);
443
-					*ticks+=(ticks_t)delta;
444
-				}else{
445
-					/*LM_DBG("incredible, but our timer is in sync with"
446
-							" real time (%lu)\n", (unsigned long)*ticks);
447
-					*/
448
-				}
449
-			}
450
-		}
451
-	}
452
-}
453
-
454
-
455
-
456
-/* time(2) equivalent, using ser internal timers (faster then a syscall) */
457
-time_t ser_time(time_t *t)
458
-{
459
-	if (likely(t==0))
460
-		return last_time.tv_sec+TICKS_TO_S(*ticks-last_ticks);
461
-	*t=last_time.tv_sec+TICKS_TO_S(*ticks-last_ticks);
462
-	return *t;
463
-}
464
-
465
-
466
-
467
-/* gettimeofday(2) equivalent, using ser internal timers (faster
468
- * but more imprecise)
469
- * WARNING: ignores tz (it's obsolete anyway)*/
470
-int ser_gettimeofday(struct timeval* tv, struct timezone* tz)
471
-{
472
-	if (likely(tv!=0)){
473
-		tv->tv_sec=last_time.tv_sec+TICKS_TO_S(*ticks-last_ticks);
474
-		tv->tv_usec=last_time.tv_usec+
475
-					(TICKS_TO_MS(*ticks-last_ticks)%1000)*1000;
476
-	}
477
-	return 0;
478
-}
479
-
480
-
481
-
482
-#ifdef DBG_ser_time
483
-/* debugging  only, remove */
484
-void check_ser_drift()
485
-{
486
-	time_t t1, t2;
487
-	struct timeval tv1, tv2;
488
-	int r;
489
-
490
-	t1=time(0);
491
-	t2=ser_time(0);
492
-	if (t1!=t2)
493
-		BUG("time(0)!=ser_time(0) : %d != %d \n", (unsigned)t1, (unsigned)t2);
494
-
495
-	r=gettimeofday(&tv1, 0);
496
-	ser_gettimeofday(&tv2, 0);
497
-	if (tv1.tv_sec!=tv2.tv_sec)
498
-		BUG("gettimeofday seconds!=ser_gettimeofday seconds : %d != %d \n",
499
-				(unsigned)tv1.tv_sec, (unsigned)tv2.tv_sec);
500
-	else if ((tv1.tv_usec > tv2.tv_usec) &&
501
-				(unsigned)(tv1.tv_usec-tv2.tv_usec)>100000)
502
-		BUG("gettimeofday usecs > ser_gettimeofday with > 0.1s : %d ms\n",
503
-			(unsigned)(tv1.tv_usec-tv2.tv_usec)/1000);
504
-	else if ((tv1.tv_usec < tv2.tv_usec) &&
505
-				(unsigned)(tv2.tv_usec-tv1.tv_usec)>100000)
506
-		BUG("gettimeofday usecs < ser_gettimeofday with > 0.1s : %d ms\n",
507
-			(unsigned)(tv2.tv_usec-tv1.tv_usec)/1000);
508
-}
509
-#endif /* DBG_ser_time */
510
-
511
-
512
-
513
-struct timer_ln* timer_alloc()
514
-{
515
-	return shm_malloc(sizeof(struct timer_ln));
516
-}
517
-
518
-void timer_free(struct timer_ln* t)
519
-{
520
-	shm_free(t);
521
-}
522
-
523
-
524
-/* unsafe (no lock ) timer add function
525
- * t = current ticks
526
- * tl must be filled (the intial_timeout and flags must be set)
527
- * returns -1 on error, 0 on success */
528
-static inline int _timer_add(ticks_t t, struct timer_ln* tl)
529
-{
530
-	ticks_t delta;
531
-
532
-#ifdef USE_SLOW_TIMER
533
-	tl->flags&=~((unsigned short)F_TIMER_ON_SLOW_LIST);
534
-	tl->slow_idx=0;
535
-#endif
536
-	delta=tl->initial_timeout;
537
-	tl->expire=t+delta;
538
-	return _timer_dist_tl(tl, delta);
539
-}
540
-
541
-
542
-
543
-/* "public", safe timer add functions
544
- * adds a timer at delta ticks from the current time
545
- * returns -1 on error, 0 on success
546
- * WARNING: to re-add an expired or deleted timer you must call
547
- *          timer_reinit(tl) prior to timer_add
548
- *          The default behaviour allows timer_add to add a timer only if it
549
- *          has never been added before.
550
- */
551
-#ifdef TIMER_DEBUG
552
-int timer_add_safe(struct timer_ln* tl, ticks_t delta,
553
-					const char* file, const char* func, unsigned line)
554
-#else
555
-int timer_add_safe(struct timer_ln* tl, ticks_t delta)
556
-#endif
557
-{
558
-	int ret;
559
-
560
-	LOCK_TIMER_LIST();
561
-	if (tl->flags & F_TIMER_ACTIVE){
562
-#ifdef TIMER_DEBUG
563
-		LOG(timerlog, "timer_add called on an active timer %p (%p, %p),"
564
-					" flags %x\n", tl, tl->next, tl->prev, tl->flags);
565
-		LOG(timerlog, "WARN: -timer_add-; called from %s(%s):%d\n",
566
-					func, file, line);
567
-		LOG(timerlog, "WARN: -timer_add-: added %d times"
568
-					", last from: %s(%s):%d, deleted %d times"
569
-					", last from: %s(%s):%d, init %d times, expired %d \n",
570
-					tl->add_calls, tl->add_func, tl->add_file, tl->add_line,
571
-					tl->del_calls, tl->del_func, tl->del_file, tl->del_line,
572
-					tl->init, tl->expires_no);
573
-#else
574
-		LM_DBG("timer_add called on an active timer %p (%p, %p),"
575
-					" flags %x\n", tl, tl->next, tl->prev, tl->flags);
576
-#endif
577
-		ret=-1; /* refusing to add active or non-reinit. timer */
578
-		goto error;
579
-	}
580
-	tl->initial_timeout=delta;
581
-	if ((tl->next!=0) || (tl->prev!=0)){
582
-		LM_CRIT("timer_add: called with linked timer: %p (%p, %p)\n",
583
-				tl, tl->next, tl->prev);
584
-		ret=-1;
585
-		goto error;
586
-	}
587
-	tl->flags|=F_TIMER_ACTIVE;
588
-#ifdef TIMER_DEBUG
589
-	tl->add_file=file;
590
-	tl->add_func=func;
591
-	tl->add_line=line;
592
-	tl->add_calls++;
593
-#endif
594
-	ret=_timer_add(*ticks, tl);
595
-error:
596
-	UNLOCK_TIMER_LIST();
597
-	return ret;
598
-}
599
-
600
-
601
-
602
-/* safe timer delete
603
- * deletes tl and inits the list pointer to 0
604
- * returns  <0 on error (-1 if timer not active/already deleted and -2 if
605
- *           delete attempted from the timer handler) and 0 on success
606
- */
607
-#ifdef TIMER_DEBUG
608
-int timer_del_safe(struct timer_ln* tl,
609
-					const char* file, const char* func, unsigned line)
610
-#else
611
-int timer_del_safe(struct timer_ln* tl)
612
-#endif
613
-{
614
-	int ret;
615
-
616
-	ret=-1;
617
-again:
618
-	/* quick exit if timer inactive */
619
-	if ( !(tl->flags & F_TIMER_ACTIVE)){
620
-#ifdef TIMER_DEBUG
621
-		LOG(timerlog, "timer_del called on an inactive timer %p (%p, %p),"
622
-					" flags %x\n", tl, tl->next, tl->prev, tl->flags);
623
-		LOG(timerlog, "WARN: -timer_del-; called from %s(%s):%d\n",
624
-					func, file, line);
625
-		LOG(timerlog, "WARN: -timer_del-: added %d times"
626
-					", last from: %s(%s):%d, deleted %d times"
627
-					", last from: %s(%s):%d, init %d times, expired %d \n",
628
-					tl->add_calls, tl->add_func, tl->add_file, tl->add_line,
629
-					tl->del_calls, tl->del_func, tl->del_file, tl->del_line,
630
-					tl->init, tl->expires_no);
631
-#else
632
-/*
633
-		LM_DBG("called on an inactive timer %p (%p, %p),"
634
-					" flags %x\n", tl, tl->next, tl->prev, tl->flags);
635
-*/
636
-#endif
637
-		return -1;
638
-	}
639
-#ifdef USE_SLOW_TIMER
640
-		if (IS_ON_SLOW_LIST(tl) && (tl->slow_idx!=*t_idx)){
641
-			LOCK_SLOW_TIMER_LIST();
642
-			if (!IS_ON_SLOW_LIST(tl) || (tl->slow_idx==*t_idx)){
643
-				UNLOCK_SLOW_TIMER_LIST();
644
-				goto again;
645
-			}
646
-			if (IS_RUNNING_SLOW(tl)){
647
-				UNLOCK_SLOW_TIMER_LIST();
648
-				if (IS_IN_TIMER_SLOW()){
649
-					/* if somebody tries to shoot himself in the foot,
650
-					 * warn him and ignore the delete */
651
-					LM_CRIT("timer handle %p (s) tried to delete"
652
-							" itself\n", tl);
653
-#ifdef TIMER_DEBUG
654
-					LOG(timerlog, "WARN: -timer_del-: called from %s(%s):%d\n",
655
-									func, file, line);
656
-					LOG(timerlog, "WARN: -timer_del-: added %d times"
657
-						", last from: %s(%s):%d, deleted %d times"
658
-						", last from: %s(%s):%d, init %d times, expired %d \n",
659
-						tl->add_calls, tl->add_func, tl->add_file,
660
-						tl->add_line, tl->del_calls, tl->del_func,
661
-						tl->del_file, tl->del_line, tl->init, tl->expires_no);
662
-#endif
663
-					return -2; /* do nothing */
664
-				}
665
-				sched_yield(); /* wait for it to complete */
666
-				goto again;
667
-			}
668
-			if (tl->next!=0){
669
-				_timer_rm_list(tl); /* detach */
670
-				tl->next=tl->prev=0;
671
-				ret=0;
672
-#ifdef TIMER_DEBUG
673
-				tl->del_file=file;
674
-				tl->del_func=func;
675
-				tl->del_line=line;
676
-				tl->flags|=F_TIMER_DELETED;
677
-#endif
678
-			}else{
679
-#ifdef TIMER_DEBUG
680
-				LOG(timerlog, "timer_del: (s) timer %p (%p, %p) flags %x "
681
-							"already detached\n",
682
-							tl, tl->next, tl->prev, tl->flags);
683
-				LOG(timerlog, "WARN: -timer_del-: @%d tl=%p "
684
-					"{ %p, %p, %d, %d, %p, %p, %04x, -}\n", get_ticks_raw(),
685
-					tl,  tl->next, tl->prev, tl->expire, tl->initial_timeout,
686
-					tl->data, tl->f, tl->flags);
687
-				LOG(timerlog, "WARN: -timer_del-; called from %s(%s):%d\n",
688
-						func, file, line);
689
-				LOG(timerlog, "WARN: -timer_del-: added %d times"
690
-						", last from: %s(%s):%d, deleted %d times"
691
-						", last from: %s(%s):%d, init %d times, expired %d \n",
692
-						tl->add_calls,
693
-						tl->add_func, tl->add_file, tl->add_line,
694
-						tl->del_calls,
695
-						tl->del_func, tl->del_file, tl->del_line,
696
-						tl->init, tl->expires_no);
697
-#else
698
-/*
699
-				LM_DBG("(s) timer %p (%p, %p) flags %x "
700
-							"already detached\n",
701
-							tl, tl->next, tl->prev, tl->flags);
702
-*/
703
-#endif
704
-				ret=-1;
705
-			}
706
-			UNLOCK_SLOW_TIMER_LIST();
707
-		}else{
708
-#endif
709
-			LOCK_TIMER_LIST();
710
-#ifdef USE_SLOW_TIMER
711
-			if (IS_ON_SLOW_LIST(tl) && (tl->slow_idx!=*t_idx)){
712
-				UNLOCK_TIMER_LIST();
713
-				goto again;
714
-			}
715
-#endif
716
-			if (IS_RUNNING(tl)){
717
-				UNLOCK_TIMER_LIST();
718
-				if (IS_IN_TIMER()){
719
-					/* if somebody tries to shoot himself in the foot,
720
-					 * warn him and ignore the delete */
721
-					LM_CRIT("timer handle %p tried to delete"
722
-							" itself\n", tl);
723
-#ifdef TIMER_DEBUG
724
-					LOG(timerlog, "WARN: -timer_del-: called from %s(%s):%d\n",
725
-									func, file, line);
726
-					LOG(timerlog, "WARN: -timer_del-: added %d times"
727
-						", last from: %s(%s):%d, deleted %d times"
728
-						", last from: %s(%s):%d, init %d times, expired %d \n",
729
-						tl->add_calls, tl->add_func, tl->add_file,
730
-						tl->add_line, tl->del_calls, tl->del_func,
731
-						tl->del_file, tl->del_line, tl->init, tl->expires_no);
732
-#endif
733
-					return -2; /* do nothing */
734
-				}
735
-				sched_yield(); /* wait for it to complete */
736
-				goto again;
737
-			}
738
-			if ((tl->next!=0)&&(tl->prev!=0)){
739
-				_timer_rm_list(tl); /* detach */
740
-				tl->next=tl->prev=0;
741
-				ret=0;
742
-#ifdef TIMER_DEBUG
743
-				tl->del_file=file;
744
-				tl->del_func=func;
745
-				tl->del_line=line;
746
-				tl->flags|=F_TIMER_DELETED;
747
-#endif
748
-			}else{
749
-#ifdef TIMER_DEBUG
750
-				LOG(timerlog, "timer_del: (f) timer %p (%p, %p) flags %x "
751
-							"already detached\n",
752
-							tl, tl->next, tl->prev, tl->flags);
753
-				LOG(timerlog, "WARN: -timer_del-: @%d tl=%p "
754
-					"{ %p, %p, %d, %d, %p, %p, %04x, -}\n", get_ticks_raw(),
755
-					tl,  tl->next, tl->prev, tl->expire, tl->initial_timeout,
756
-					tl->data, tl->f, tl->flags);
757
-				LOG(timerlog, "WARN: -timer_del-; called from %s(%s):%d\n",
758
-						func, file, line);
759
-				LOG(timerlog, "WARN: -timer_del-: added %d times"
760
-						", last from: %s(%s):%d, deleted %d times"
761
-						", last from: %s(%s):%d, init %d times, expired %d \n",
762
-						tl->add_calls,
763
-						tl->add_func, tl->add_file, tl->add_line,
764
-						tl->del_calls,
765
-						tl->del_func, tl->del_file, tl->del_line,
766
-						tl->init, tl->expires_no);
767
-#else
768
-/*
769
-				LM_DBG("(f) timer %p (%p, %p) flags %x "
770
-							"already detached\n",
771
-							tl, tl->next, tl->prev, tl->flags);
772
-*/
773
-#endif
774
-				ret=-1;
775
-			}
776
-			UNLOCK_TIMER_LIST();
777
-#ifdef USE_SLOW_TIMER
778
-		}
779
-#endif
780
-return ret;
781
-}
782
-
783
-
784
-
785
-/* marks a timer as "to be deleted when the handler ends", usefull when
786
- * the timer handler knows it won't prolong the timer anymore (it will
787
- * return 0) and will do some time consuming work. Calling this function
788
- * will cause simultaneous timer_dels to return immediately (they won't
789
- * wait anymore for the timer handle to finish). It will also allow
790
- * self-deleting from the timer handle without bug reports.
791
- * WARNING: - if you rely on timer_del to know when the timer handle execution
792
- *            finishes (e.g. to free resources used in the timer handle), don't
793
- *            use this function.
794
- *          - this function can be called only from a timer handle (in timer
795
- *            context), all other calls will have no effect and will log a
796
- *            bug message
797
- */
798
-void timer_allow_del(void)
799
-{
800
-	if (IS_IN_TIMER() ){
801
-			UNSET_RUNNING();
802
-	}else
803
-#ifdef USE_SLOW_TIMER
804
-	if (IS_IN_TIMER_SLOW()){
805
-			UNSET_RUNNING_SLOW();
806
-	}else
807
-#endif
808
-		LM_CRIT("timer_allow_del called outside a timer handle\n");
809
-}
810
-
811
-
812
-/* called from timer_handle, must be called with the timer lock held
813
- * WARNING: expired one shot timers are _not_ automatically reinit
814
- *          (because they could have been already freed from the timer
815
- *           handler so a reinit would not be safe!) */
816
-inline static void timer_list_expire(ticks_t t, struct timer_head* h
817
-#ifdef USE_SLOW_TIMER
818
-										, struct timer_head* slow_l,
819
-										slow_idx_t slow_mark
820
-#endif
821
-																	)
822
-{
823
-	struct timer_ln * tl;
824
-	ticks_t ret;
825
-#ifdef TIMER_DEBUG
826
-	struct timer_ln* first;
827
-	int i=0;
828
-
829
-	first=h->next;
830
-#endif
831
-
832
-	/*LM_DBG("@ ticks = %lu, list =%p\n",
833
-			(unsigned long) *ticks, h);
834
-	*/
835
-	while(h->next!=(struct timer_ln*)h){
836
-		tl=h->next;
837
-#ifdef TIMER_DEBUG /* FIXME: replace w/ EXTRA_DEBUG */
838
-		if (tl==0){
839
-			LM_CRIT("timer_list_expire: tl=%p, h=%p {%p, %p}\n",
840
-					tl, h, h->next, h->prev);
841
-			abort();
842
-		}else if((tl->next==0) || (tl->prev==0)){
843
-			LM_CRIT("timer_list_expire: @%d tl=%p "
844
-					"{ %p, %p, %d, %d, %p, %p, %04x, -},"
845
-					" h=%p {%p, %p}\n", t,
846
-					tl,  tl->next, tl->prev, tl->expire, tl->initial_timeout,
847
-					tl->data, tl->f, tl->flags,
848
-					h, h->next, h->prev);
849
-			LM_CRIT("-timer_list_expire-: cycle %d, first %p,"
850
-						"running %p\n", i, first, *running_timer);
851
-			LM_CRIT("-timer_list_expire-: added %d times"
852
-						", last from: %s(%s):%d, deleted %d times"
853
-						", last from: %s(%s):%d, init %d times, expired %d \n",
854
-						tl->add_calls,
855
-						tl->add_func, tl->add_file, tl->add_line,
856
-						tl->del_calls,
857
-						tl->del_func, tl->del_file, tl->del_line,
858
-						tl->init, tl->expires_no);
859
-			abort();
860
-		}
861
-		i++;
862
-#endif
863
-		_timer_rm_list(tl); /* detach */
864
-#ifdef USE_SLOW_TIMER
865
-		if (IS_FAST_TIMER(tl)){
866
-#endif
867
-		/* if fast timer */
868
-			SET_RUNNING(tl);
869
-			tl->next=tl->prev=0; /* debugging */
870
-#ifdef TIMER_DEBUG
871
-			tl->expires_no++;
872
-#endif
873
-			UNLOCK_TIMER_LIST(); /* acts also as write barrier */
874
-				ret=tl->f(t, tl, tl->data);
875
-				/* reset the configuration group handles */
876
-				cfg_reset_all();
877
-				if (ret==0){
878
-					UNSET_RUNNING();
879
-					LOCK_TIMER_LIST();
880
-				}else{
881
-					/* not one-shot, re-add it */
882
-					LOCK_TIMER_LIST();
883
-					if (ret!=(ticks_t)-1) /* ! periodic */
884
-						tl->initial_timeout=ret;
885
-					_timer_add(t, tl);
886
-					UNSET_RUNNING();
887
-				}
888
-#ifdef USE_SLOW_TIMER
889
-		}else{
890
-			/* slow timer */
891
-			SET_SLOW_LIST(tl);
892
-			tl->slow_idx=slow_mark; /* current index */
893
-			/* overflow check in timer_handler*/
894
-			_timer_add_list(slow_l, tl);
895
-
896
-		}
897
-#endif
898
-	}
899
-}
900
-
901
-
902
-
903
-/* "main" timer routine