readchar fix
[vde.git] / vde-2 / qtimer.c
blob95b7df066d453a4dfb7b3d591dc95b0115456b68
1 /*
2 * Copyright 2005 Renzo Davoli
3 * Licensed under the GPLv2
4 */
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <signal.h>
9 #include <sys/time.h>
10 #include <syslog.h>
11 #include <errno.h>
12 #include <string.h>
13 #include <switch.h>
14 #include <stdio.h>
15 #include <consmgmt.h> /* just for printlog def */
17 #define QT_ALLOC_STEP 4
19 struct qt_timer {
20 int qt_n; //timer ID
21 time_t qt_period; //timer period
22 time_t qt_nextcall; //next call time (in secs)
23 unsigned int qt_times; //number of times to be activated <0 = infinity
24 void (* qt_call)(); //funct. to call
25 void *qt_arg; // opt arg to the funct.
28 struct qt_timer **qth; // head of the active timer array
29 struct qt_timer *qtf; // free list
30 int maxqt; //size of active timer array
32 static time_t gqtime; // global time in secs, secs from the epoch
33 static int activeqt; // number of active timers
34 static int countqt; // counter for timer ID
36 time_t qtime() // returns global time (faster than time())
38 return gqtime;
41 static sigset_t ss_alarm, ss_old;
42 void qtime_csenter()
44 if (sigprocmask(SIG_BLOCK,&ss_alarm,&ss_old) < 0)
45 printlog(LOG_WARNING,"error qtime_csenter\n");
48 void qtime_csexit()
50 if (sigprocmask(SIG_SETMASK,&ss_old,NULL) < 0)
51 printlog(LOG_WARNING,"error qtime_csexit\n");
54 unsigned int qtimer_add(time_t period,int times,void (*call)(),void *arg)
56 register int n;
57 if (period>0 && call && times>=0) {
58 qtime_csenter();
59 if (activeqt >= maxqt) {
60 int newmaxqt=maxqt+QT_ALLOC_STEP;
61 qth=realloc(qth,newmaxqt*sizeof(struct qt_timer *));
62 if (qth == NULL) {
63 return -1;
65 /* it is not possible to use unitialized elements */
66 /*memset(qth+maxqt,0,QT_ALLOC_STEP*sizeof(struct qt_timer *));*/
67 maxqt=newmaxqt;
69 n=activeqt++;
70 if (qtf == NULL) {
71 qtf=malloc(sizeof(struct qt_timer));
72 if (qth == NULL) {
73 return -1;
75 /*all the fields but qt_arg get initialized */
76 /*memset(qtf,0,sizeof(struct qt_timer));*/
77 qtf->qt_arg=NULL;
79 qth[n]=qtf;
80 qtf=qtf->qt_arg;
81 qth[n]->qt_n=countqt++;
82 qth[n]->qt_period=period;
83 qth[n]->qt_nextcall=gqtime+period;
84 qth[n]->qt_call=call;
85 qth[n]->qt_arg=arg;
86 qth[n]->qt_times=(times==0)?-1:times;
87 qtime_csexit();
88 return qth[n]->qt_n;
89 } else
90 return -1;
93 void qtimer_del(unsigned int n)
95 register int i;
96 for (i=0; i<activeqt; i++) {
97 if (n==qth[i]->qt_n) {
98 qth[i]->qt_times=0;
99 break;
104 static void sig_alarm(int sig)
106 register int i;
107 register int j;
108 gqtime++;
109 //printf("%d\n",gqtime);
110 for (i=0,j=0; i<activeqt; i++) {
111 if (qth[i]->qt_times == 0)
113 //printf("timer %d eliminated\n",qth[i]->qt_n);
114 qth[i]->qt_arg=qtf;
115 qtf=qth[i];
117 else {
118 if (gqtime >= qth[i]->qt_nextcall) {
119 //printf("timer %d fires\n",qth[i]->qt_n);
120 qth[i]->qt_call(qth[i]->qt_arg);
121 qth[i]->qt_nextcall+=qth[i]->qt_period;
122 if (qth[i]->qt_times > 0 )
123 (qth[i]->qt_times)--;
125 //printf("%d -> %d \n",i,j);
126 if (i-j) qth[j]=qth[i];
127 j++;
130 activeqt=j;
133 void qtimer_init()
135 struct itimerval it;
136 struct sigaction sa;
138 sa.sa_handler = sig_alarm;
139 sa.sa_flags = SA_RESTART;
140 if(sigaction(SIGALRM, &sa, NULL) < 0){
141 printlog(LOG_WARNING,"Setting handler for SIGALRM %s", strerror(errno));
142 return;
145 sigemptyset(&ss_alarm);
146 sigaddset(&ss_alarm,SIGALRM);
148 it.it_value.tv_sec = 1;
149 it.it_value.tv_usec = 0 ;
150 it.it_interval.tv_sec = 1;
151 it.it_interval.tv_usec = 0 ;
152 setitimer(ITIMER_REAL, &it, NULL);
156 * test stub */
158 void fun(void *arg)
160 printf("FUN\n");
163 main()
165 qtimer_init();
166 qtimer_add(7,0,fun,NULL);
167 qtimer_add(3,0,fun,NULL);
168 qtimer_add(4,2,fun,NULL);
169 while(1)
170 pause();