2 * Copyright 2005 Renzo Davoli
3 * Licensed under the GPLv2
16 #define QT_ALLOC_STEP 4
20 time_t qt_period
; //timer period
21 time_t qt_nextcall
; //next call time (in secs)
22 unsigned int qt_times
; //number of times to be activated <0 = infinity
23 void (* qt_call
)(); //funct. to call
24 void *qt_arg
; // opt arg to the funct.
27 struct qt_timer
**qth
; // head of the active timer array
28 struct qt_timer
*qtf
; // free list
29 int maxqt
; //size of active timer array
31 static time_t gqtime
; // global time in secs, secs from the epoch
32 static int activeqt
; // number of active timers
33 static int countqt
; // counter for timer ID
35 time_t qtime() // returns global time (faster than time())
40 static sigset_t ss_alarm
, ss_old
;
43 if (sigprocmask(SIG_BLOCK
,&ss_alarm
,&ss_old
) < 0)
44 printlog(LOG_WARNING
,"error qtime_csenter\n");
49 if (sigprocmask(SIG_SETMASK
,&ss_old
,NULL
) < 0)
50 printlog(LOG_WARNING
,"error qtime_csexit\n");
53 unsigned int qtimer_add(time_t period
,int times
,void (*call
)(),void *arg
)
56 if (period
>0 && call
&& times
>=0) {
58 if (activeqt
>= maxqt
) {
59 int newmaxqt
=maxqt
+QT_ALLOC_STEP
;
60 qth
=realloc(qth
,newmaxqt
*sizeof(struct qt_timer
*));
64 /* it is not possible to use unitialized elements */
65 /*memset(qth+maxqt,0,QT_ALLOC_STEP*sizeof(struct qt_timer *));*/
70 qtf
=malloc(sizeof(struct qt_timer
));
74 /*all the fields but qt_arg get initialized */
75 /*memset(qtf,0,sizeof(struct qt_timer));*/
80 qth
[n
]->qt_n
=countqt
++;
81 qth
[n
]->qt_period
=period
;
82 qth
[n
]->qt_nextcall
=gqtime
+period
;
85 qth
[n
]->qt_times
=(times
==0)?-1:times
;
92 void qtimer_del(unsigned int n
)
95 for (i
=0; i
<activeqt
; i
++) {
96 if (n
==qth
[i
]->qt_n
) {
103 static void sig_alarm(int sig
)
108 //printf("%d\n",gqtime);
109 for (i
=0,j
=0; i
<activeqt
; i
++) {
110 if (qth
[i
]->qt_times
== 0)
112 //printf("timer %d eliminated\n",qth[i]->qt_n);
117 if (gqtime
>= qth
[i
]->qt_nextcall
) {
118 //printf("timer %d fires\n",qth[i]->qt_n);
119 qth
[i
]->qt_call(qth
[i
]->qt_arg
);
120 qth
[i
]->qt_nextcall
+=qth
[i
]->qt_period
;
121 if (qth
[i
]->qt_times
> 0 )
122 (qth
[i
]->qt_times
)--;
124 //printf("%d -> %d \n",i,j);
125 if (i
-j
) qth
[j
]=qth
[i
];
137 sa
.sa_handler
= sig_alarm
;
138 sa
.sa_flags
= SA_RESTART
;
139 if(sigaction(SIGALRM
, &sa
, NULL
) < 0){
140 printlog(LOG_WARNING
,"Setting handler for SIGALRM %s", strerror(errno
));
144 sigemptyset(&ss_alarm
);
145 sigaddset(&ss_alarm
,SIGALRM
);
147 it
.it_value
.tv_sec
= 1;
148 it
.it_value
.tv_usec
= 0 ;
149 it
.it_interval
.tv_sec
= 1;
150 it
.it_interval
.tv_usec
= 0 ;
151 setitimer(ITIMER_REAL
, &it
, NULL
);
165 qtimer_add(7,0,fun,NULL);
166 qtimer_add(3,0,fun,NULL);
167 qtimer_add(4,2,fun,NULL);