4 * $Id: events.c,v 1.1.1.1 2005/04/29 01:44:51 echo Exp $
26 /* Type definitions */
27 typedef struct _EventList_t {
29 struct _EventList_t *next;
30 struct _EventList_t *prev;
33 typedef struct _HFList_t {
37 struct _HFList_t *next;
40 typedef struct _FDList_t {
43 struct _FDList_t *next;
46 /* Local function prototypes */
47 static void events_init0(void);
48 static void events_init1(void);
49 static void events_dump(void);
50 static void events_release(void);
51 static void event_get_fds(fd_set *dest);
54 static const char *rcsid="$Id: events.c,v 1.1.1.1 2005/04/29 01:44:51 echo Exp $";
56 const Unit_t events_unit = {
64 /*static mutex_t event_mutex;*/
65 static EventList_t *eventhead, *eventtail;
66 static HFList_t *handlers[CE_MAX + 1];
67 static FDList_t *fdlist;
71 /* Initialize local data */
79 for (i = 0; i <= CE_MAX; i++) {
85 /* Initialization for data that needs other units */
89 set_var_str(&events_unit, "version", rcsid);
90 Debug_unit(&events_unit, "Initialized.");
93 /* Dump status, local data etc. */
97 const EventList_t *tmp;
102 for (tmp = eventhead; tmp != NULL; tmp = tmp->next) {
103 assert(tmp->event != NULL);
104 assert(tmp->event->unit != NULL);
105 assert(tmp->event->unit->name != NULL);
106 Debug_unit(&events_unit, "unit %s type %s data 0x%x", tmp->event->unit->name, dump_event_type(tmp->event->type), tmp->event->data);
108 for (i = 0; i <= CE_MAX; i++) {
109 for (htmp = handlers[i]; htmp != NULL; htmp = htmp->next) {
110 Debug_unit(&events_unit, "type %s func 0x%x name %s data 0x%x", dump_event_type(i), htmp->h, htmp->name, htmp->funcdata);
113 for (ftmp = fdlist; ftmp != NULL; ftmp = ftmp->next) {
114 Debug_unit(&events_unit, "polled fd %d", ftmp->fd);
118 /* Release allocated memory, close files etc. */
128 for (tmp = eventhead; tmp != NULL; ) {
129 assert(eventhead->event != NULL);
130 assert(eventhead->event->unit != NULL);
131 assert(eventhead->event->unit->name != NULL);
132 Debug_unit(&events_unit, "discarding unread event, unit %s type %s data 0x%x", eventhead->event->unit->name, dump_event_type(eventhead->event->type), eventhead->event->data);
133 tmp = eventhead->next;
134 mem_free(&events_unit, eventhead->event);
135 mem_free(&events_unit, eventhead);
140 for (i = 0; i <= CE_MAX; i++) {
141 for (htmp = handlers[i]; htmp != NULL; htmp = htmp->next) {
142 handlers[i] = htmp->next;
143 mem_free(&events_unit, htmp);
146 for (ftmp = fdlist; ftmp != NULL; ftmp = ftmp->next) {
147 printf("Closing:%d\n",ftmp->fd);
150 mem_free(&events_unit, ftmp);
155 add_event_handler(EventType_t type, HandlerFunc_t func, const char *name, void *funcdata)
159 tmp = (HFList_t *)mem_alloc(&events_unit, sizeof(HFList_t));
162 tmp->funcdata = funcdata;
163 assert(type <= CE_MAX);
164 tmp->next = handlers[type];
166 handlers[type] = tmp;
169 static const char *typetable[CE_MAX + 1] = {
179 /* Return event type as string */
181 dump_event_type(EventType_t type)
183 assert(type >= CE_SVC_CLOSE && type <= CE_MAX);
184 return typetable[type];
187 /* Get next event from queue */
191 const Event_t *event = NULL;
192 EventList_t *tmplist;
197 struct timeval *rolex;
199 while (eventtail == NULL && sig_hup == 0 &&
200 sig_usr1 == 0 && sig_alarm == 0 &&
202 /* No events waiting, sleep on select() or poll() */
203 if (fdlist != NULL) {
204 soonest = timer_find_soonest(&events_unit);
205 if (soonest != NULL) {
206 rolex = (struct timeval *)mem_alloc(&events_unit,
207 sizeof(struct timeval));
208 rolex->tv_sec = soonest->alarm_time - time(NULL);
210 Debug_unit(&events_unit, "Sleeping %d s...", rolex->tv_sec);
214 Debug_unit(&events_unit, "Sleeping forever...");
216 event_get_fds(&to_select);
217 poll_ret = select(FD_SETSIZE, &to_select, NULL, NULL, rolex);
219 mem_free(&events_unit,rolex);
220 Debug_unit(&events_unit, "Select: %d", poll_ret);
224 dump_error(&events_unit, "select");
228 timer_ack(&events_unit, soonest);
229 event_put(&events_unit, CE_TIMER, (void*)soonest->data);
232 /* Data arrival / SVC creation */
233 Debug_unit(&events_unit,"fdlist:%d",fdlist);
234 for (tmp = fdlist; tmp != NULL; tmp = tmp->next) {
235 dump_printf(EL_DEBUG,"FD:%d",tmp->fd);
236 if (FD_ISSET(tmp->fd, &to_select)) {
237 Debug_unit(&events_unit, "Event on fd %d", tmp->fd);
238 conn_set_active(tmp->data, tmp->fd);
239 event_put(&events_unit, CE_DATA, tmp->data);
246 Debug_unit(&events_unit, "No fds, restarting after 10 s");
248 event_put(&events_unit, CE_RESTART, NULL);
252 event_put(&events_unit, CE_RESTART, NULL);
256 event_put(&events_unit, CE_DUMP, NULL);
260 event_put(&events_unit, CE_EXIT, NULL);
263 if (sig_alarm != 0) {
264 event_put(&events_unit, CE_TIMER, NULL);
267 Debug_unit(&events_unit, "get event %s", dump_event_type(eventtail->event->type));
269 event = eventhead->event;
270 if (eventhead->next != NULL) {
271 eventhead->next->prev = NULL;
274 /* This was the last */
278 eventhead = eventhead->next;
280 mem_free(&events_unit, tmplist);
284 /* Add event to queue */
286 event_put(const Unit_t *unit, EventType_t type, void *data)
289 EventList_t *tmplist;
291 Debug_unit(&events_unit, "unit %s puts event %s", unit->name, dump_event_type(type));
292 event = (Event_t *)mem_alloc(&events_unit, sizeof(Event_t));
297 tmplist = (EventList_t *)mem_alloc(&events_unit, sizeof(EventList_t));
298 tmplist->event = event;
299 tmplist->next = NULL;
301 tmplist->prev = eventtail;
303 if (eventtail != NULL) {
304 eventtail->next = tmplist;
307 /* This is the first one */
314 /* Call handlers until one returns nonzero */
316 dispatch_handlers(const Event_t *event)
319 const HFList_t *htmp;
321 assert(event != NULL);
322 for (htmp = handlers[event->type]; htmp != NULL; htmp = htmp->next) {
323 Debug_unit(&events_unit, "trying handler %s", htmp->name);
324 handled = (htmp->h(event, htmp->funcdata));
326 Debug_unit(&events_unit, "success.");
330 Debug_unit(&events_unit, "failed.");
337 event_get_fds(fd_set *dest)
343 for(tmp = fdlist; tmp != NULL; tmp = tmp->next)
344 FD_SET(tmp->fd, dest);
348 event_add_fd(int fd, void *data)
352 tmp = mem_alloc(&events_unit, sizeof(FDList_t));
360 event_remove_fd(int fd)
362 FDList_t *tmp, *prev = NULL;
364 for (tmp = fdlist; tmp != NULL; prev = tmp, tmp = tmp->next) {
371 Debug_unit(&events_unit, "Could not find fd %d for removal", fd);
376 prev->next = tmp->next;
381 mem_free(&events_unit, tmp);