e363111a4da8dd83afd145cc066c1f06d9503040
[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.1  1995-03-10 18:22:44  quinn
8  * The rudiments of an asynchronous server.
9  *
10  */
11
12 #include <assert.h>
13 #include <sys/time.h>
14 #include <sys/types.h>
15 #include <unistd.h>
16 #include <stdlib.h>
17
18 #include <eventl.h>
19
20 IOCHAN iochans = 0;
21
22 IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags)
23 {
24     IOCHAN new;
25
26     if (!(new = malloc(sizeof(*new))))
27         return 0;
28     new->destroyed = 0;
29     new->fd = fd;
30     new->flags = flags;
31     new->fun = cb;
32     return new;
33 }
34
35 void iochan_destroy(IOCHAN i)
36 {
37     i->destroyed = 1;
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
48         FD_ZERO(&in);
49         FD_ZERO(&out);
50         FD_ZERO(&except);
51         for (p = iochans; p; p = p->next)
52         {
53             if (p->flags & EVENT_INPUT)
54                 FD_SET(p->fd, &in);
55             if (p->flags & EVENT_OUTPUT)
56                 FD_SET(p->fd, &out);
57             if (p->flags & EVENT_EXCEPT)
58                 FD_SET(p->fd, &except);
59             if (p->fd > max)
60                 max = p->fd;
61         }
62         if ((res = select(max + 1, &in, &out, &except, 0)) < 0)
63         {
64             if (errno == EINTR)
65                 continue;
66             return 1;
67         }
68         if (!res)
69             continue;
70         for (p = iochans; p; p = nextp)
71         {
72             nextp = p->next;
73             if (FD_ISSET(p->fd, &in))
74                 (*p->fun)(p, EVENT_INPUT);
75             if (!p->destroyed && FD_ISSET(p->fd, &in))
76                 (*p->fun)(p, EVENT_OUTPUT);
77             if (!p->destroyed && FD_ISSET(p->fd, &except))
78                 (*p->fun)(p, EVENT_EXCEPT);
79             if (p->destroyed)
80             {
81                 IOCHAN tmp = p, pr;
82
83                 if (p == iochans)
84                     iochans = p->next;
85                 else
86                 {
87                     for (pr = iochans; pr; pr = pr->next)
88                         if (pr->next == p)
89                             break;
90                     assert(pr);
91                     pr->next = p->next;
92                 }
93                 if (nextp == p)
94                     nextp = p->next;
95                 free(tmp);
96             }
97         }
98     }
99     while (iochans);
100     return 0;
101 }