added fast(er) list to be included (just in header) + small bug fix
[my-code/api.git] / event / event.c
1 /* event.c -- event management stuff
2  *
3  * author: hackbard@hackdaworld.dyndns.org
4  *
5  */
6
7 #include "event.h"
8
9 int event_init(t_event *event,int outfd) {
10
11   dprintf(outfd,"[event] initializing event system ...\n");
12
13   event->maxfd=0;
14
15   event->outfd=outfd;
16
17   FD_ZERO(&(event->rfds));
18   FD_ZERO(&(event->rfds_o));
19   FD_ZERO(&(event->wfds));
20   FD_ZERO(&(event->wfds_o));
21
22   return E_SUCCESS;
23 }
24
25 int event_set_timeout(t_event *event,int sec,int usec) {
26
27   event->timeout.tv_sec=sec;
28   event->timeout.tv_usec=usec;
29
30   return E_SUCCESS;
31 }
32
33 int event_set_immediately(t_event *event,unsigned char value) {
34
35   if(value==IMM_TRUE)
36     event->immediately=value;
37
38   return E_SUCCESS;
39 }
40
41 int event_math(int fd,t_event *event,char rw,char ar) {
42
43   if(ar==ADD) {
44     if(rw==READ) FD_SET(fd,&(event->rfds_o));
45     else FD_SET(fd,&(event->wfds_o));
46     if(fd>event->maxfd) event->maxfd=fd;
47   } else {
48     if(rw==READ) FD_CLR(fd,&(event->rfds_o));
49     else FD_CLR(fd,&(event->wfds_o));
50     if(fd==event->maxfd) event->maxfd-=1;
51   }
52
53   dprintf(event->outfd,"[event] %c fd %d to %c file descriptor set\n",
54           ar==ADD?'+':'-',fd,rw==READ?'r':'w');
55
56   return E_SUCCESS;
57 }
58
59 int event_start(t_event *event,void *ptr,
60                 int (*callback0)(t_event *event,void *ptr),
61                 int (*callback1)(t_event *event,void *ptr)) {
62
63   int s_ret;
64   struct timeval tv;
65   struct timeval *tv_ptr;
66
67   /* switch on event system */
68   event->status=ENABLED;
69
70   while(event->status&ENABLED) {
71
72     event->rfds=event->rfds_o;
73     event->wfds=event->wfds_o;
74     tv=event->timeout;
75
76     if((tv.tv_sec==0)&&(tv.tv_usec==0)&&(!(event->immediately))) tv_ptr=NULL;
77     else tv_ptr=&tv;
78
79     if((s_ret=select(event->maxfd+1,&(event->rfds),&(event->wfds),NULL,
80                      tv_ptr))==-1) {
81       perror("[event] select call");
82       return E_ERROR;
83     }
84
85     if(s_ret) {
86       /* 1+ fd(s) available for reading/writing */
87       if(callback0(event,ptr)==CALLBACK_ERROR) {
88         dprintf(event->outfd,"[event] callback0 returned error\n");
89         return E_ERROR;
90       }
91     }
92
93     /* usual stuff to be executed */
94     if(callback1(event,ptr)==CALLBACK_ERROR) {
95       dprintf(event->outfd,"[event] callback returned error\n");
96       return E_ERROR;
97     }
98
99   }
100
101   return E_SUCCESS;
102 }
103
104 int event_check(t_event *event,int fd) {
105
106   if(FD_ISSET(fd,&(event->wfds))|FD_ISSET(fd,&(event->rfds))) return E_FD_YES;
107   else return E_FD_NO;
108
109 }
110
111 int event_stop(t_event *event) {
112
113   dprintf(event->outfd,"[event] shutdown\n");
114   event->status=DISABLED;
115
116   return E_SUCCESS;
117 }