More work on demo server.
[yaz-moved-to-github.git] / server / eventl.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: eventl.c,v $
7  * Revision 1.2  1995-03-14 10:27:59  quinn
8  * More work on demo server.
9  *
10  * Revision 1.1  1995/03/10  18:22:44  quinn
11  * The rudiments of an asynchronous server.
12  *
13  */
14
15 #include <assert.h>
16 #include <sys/time.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20
21 #include <eventl.h>
22
23 IOCHAN iochans = 0;
24
25 IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags)
26 {
27     IOCHAN new;
28
29     if (!(new = malloc(sizeof(*new))))
30         return 0;
31     new->destroyed = 0;
32     new->fd = fd;
33     new->flags = flags;
34     new->fun = cb;
35     new->next = iochans;
36     iochans = new;
37     return new;
38 }
39
40 int event_loop()
41 {
42     do
43     {
44         IOCHAN p, nextp;
45         fd_set in, out, except;
46         int res, max;
47         static struct timeval nullto = {0, 0};
48         struct timeval *timeout;
49
50         FD_ZERO(&in);
51         FD_ZERO(&out);
52         FD_ZERO(&except);
53         timeout = 0; /* hang on select */
54         for (p = iochans; p; p = p->next)
55         {
56             if (p->force_event)
57                 timeout = &nullto;
58             if (p->flags & EVENT_INPUT)
59                 FD_SET(p->fd, &in);
60             if (p->flags & EVENT_OUTPUT)
61                 FD_SET(p->fd, &out);
62             if (p->flags & EVENT_EXCEPT)
63                 FD_SET(p->fd, &except);
64             if (p->fd > max)
65                 max = p->fd;
66         }
67         if ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
68         {
69             if (errno == EINTR)
70                 continue;
71             return 1;
72         }
73         if (!res)
74             continue;
75         for (p = iochans; p; p = nextp)
76         {
77             int force_event = p->force_event;
78
79             p->force_event = 0;
80             nextp = p->next;
81             if (FD_ISSET(p->fd, &in) || force_event == EVENT_INPUT)
82                 (*p->fun)(p, EVENT_INPUT);
83             if (!p->destroyed && (FD_ISSET(p->fd, &in) ||
84                  force_event == EVENT_OUTPUT))
85                 (*p->fun)(p, EVENT_OUTPUT);
86             if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
87                 force_event == EVENT_EXCEPT))
88                 (*p->fun)(p, EVENT_EXCEPT);
89             if (p->destroyed)
90             {
91                 IOCHAN tmp = p, pr;
92
93                 if (p == iochans)
94                     iochans = p->next;
95                 else
96                 {
97                     for (pr = iochans; pr; pr = pr->next)
98                         if (pr->next == p)
99                             break;
100                     assert(pr);
101                     pr->next = p->next;
102                 }
103                 if (nextp == p)
104                     nextp = p->next;
105                 free(tmp);
106             }
107         }
108     }
109     while (iochans);
110     return 0;
111 }