New syntax in vdeq for qemu 0.8.0 compatibility
[vde.git] / vde-2 / qtimer.c
blobdba95c8e2fe981f7f13f9251be44001c9e3f27bb
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <signal.h>
4 #include <sys/time.h>
5 #include <syslog.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <switch.h>
9 #include <consmgmt.h>
11 #define QT_ALLOC_STEP 4
13 struct qt_timer {
14 int qt_n; //timer ID
15 time_t qt_period; //timer period
16 time_t qt_nextcall; //next call time (in secs)
17 unsigned int qt_times; //number of times to be activated <0 = infinity
18 void (* qt_call)(); //funct. to call
19 void *qt_arg; // opt arg to the funct.
22 struct qt_timer **qth; // head of the active timer array
23 struct qt_timer *qtf; // free list
24 int maxqt; //size of active timer array
26 static time_t gqtime; // global time in secs, secs from the epoch
27 static int activeqt; // number of active timers
28 static int countqt; // counter for timer ID
30 time_t qtime() // returns global time (faster than time())
32 return gqtime;
35 static sigset_t ss_alarm, ss_old;
36 void qtime_csenter()
38 if (sigprocmask(SIG_BLOCK,&ss_alarm,&ss_old) < 0)
39 printlog(LOG_WARNING,"error qtime_csenter\n");
42 void qtime_csexit()
44 if (sigprocmask(SIG_SETMASK,&ss_old,NULL) < 0)
45 printlog(LOG_WARNING,"error qtime_csexit\n");
48 unsigned int qtimer_add(time_t period,int times,void (*call)(),void *arg)
50 register int n;
51 if (period>0 && call && times>=0) {
52 qtime_csenter();
53 if (activeqt >= maxqt) {
54 int newmaxqt=maxqt+QT_ALLOC_STEP;
55 qth=realloc(qth,newmaxqt*sizeof(struct qt_timer *));
56 if (qth == NULL) {
57 return -1;
59 /* it is not possible to use unitialized elements */
60 /*memset(qth+maxqt,0,QT_ALLOC_STEP*sizeof(struct qt_timer *));*/
61 maxqt=newmaxqt;
63 n=activeqt++;
64 if (qtf == NULL) {
65 qtf=malloc(sizeof(struct qt_timer));
66 if (qth == NULL) {
67 return -1;
69 /*all the fields but qt_arg get initialized */
70 /*memset(qtf,0,sizeof(struct qt_timer));*/
71 qtf->qt_arg=NULL;
73 qth[n]=qtf;
74 qtf=qtf->qt_arg;
75 qth[n]->qt_n=countqt++;
76 qth[n]->qt_period=period;
77 qth[n]->qt_nextcall=gqtime+period;
78 qth[n]->qt_call=call;
79 qth[n]->qt_arg=arg;
80 qth[n]->qt_times=(times==0)?-1:times;
81 qtime_csexit();
82 return qth[n]->qt_n;
83 } else
84 return -1;
87 void qtimer_del(unsigned int n)
89 register int i;
90 for (i=0; i<activeqt; i++) {
91 if (n==qth[i]->qt_n) {
92 qth[i]->qt_times=0;
93 break;
98 static void sig_alarm(int sig)
100 register int i;
101 register int j;
102 gqtime++;
103 //printf("%d\n",gqtime);
104 for (i=0,j=0; i<activeqt; i++) {
105 if (qth[i]->qt_times == 0)
107 //printf("timer %d eliminated\n",qth[i]->qt_n);
108 qth[i]->qt_arg=qtf;
109 qtf=qth[i];
111 else {
112 if (gqtime >= qth[i]->qt_nextcall) {
113 //printf("timer %d fires\n",qth[i]->qt_n);
114 qth[i]->qt_call(qth[i]->qt_arg);
115 qth[i]->qt_nextcall+=qth[i]->qt_period;
116 if (qth[i]->qt_times > 0 )
117 (qth[i]->qt_times)--;
119 //printf("%d -> %d \n",i,j);
120 if (i-j) qth[j]=qth[i];
121 j++;
124 activeqt=j;
127 void qtimer_init()
129 struct itimerval it;
130 struct sigaction sa;
132 sa.sa_handler = sig_alarm;
133 sa.sa_flags = SA_RESTART;
134 if(sigaction(SIGALRM, &sa, NULL) < 0){
135 printlog(LOG_WARNING,"Setting handler for SIGALRM %s", strerror(errno));
136 return;
139 sigemptyset(&ss_alarm);
140 sigaddset(&ss_alarm,SIGALRM);
142 it.it_value.tv_sec = 1;
143 it.it_value.tv_usec = 0 ;
144 it.it_interval.tv_sec = 1;
145 it.it_interval.tv_usec = 0 ;
146 setitimer(ITIMER_REAL, &it, NULL);
150 * test stub */
152 void fun(void *arg)
154 printf("FUN\n");
157 main()
159 qtimer_init();
160 qtimer_add(7,0,fun,NULL);
161 qtimer_add(3,0,fun,NULL);
162 qtimer_add(4,2,fun,NULL);
163 while(1)
164 pause();