104088c9c080e581f80d68b38b22b3fadfa3c170
[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.5  1995-03-15 08:37:41  quinn
8  * Now we're pretty much set for nonblocking I/O.
9  *
10  * Revision 1.4  1995/03/14  16:59:48  quinn
11  * Bug-fixes
12  *
13  * Revision 1.3  1995/03/14  11:30:14  quinn
14  * Works better now.
15  *
16  * Revision 1.2  1995/03/14  10:27:59  quinn
17  * More work on demo server.
18  *
19  * Revision 1.1  1995/03/10  18:22:44  quinn
20  * The rudiments of an asynchronous server.
21  *
22  */
23
24 #include <assert.h>
25 #include <sys/time.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29
30 #include <eventl.h>
31
32 IOCHAN iochans = 0;
33
34 IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags)
35 {
36     IOCHAN new;
37
38     if (!(new = malloc(sizeof(*new))))
39         return 0;
40     new->destroyed = 0;
41     new->fd = fd;
42     new->flags = flags;
43     new->fun = cb;
44     new->next = iochans;
45     new->force_event = 0;
46     iochans = new;
47     return new;
48 }
49
50 int event_loop()
51 {
52     do
53     {
54         IOCHAN p, nextp;
55         fd_set in, out, except;
56         int res, max;
57         static struct timeval nullto = {0, 0};
58         struct timeval *timeout;
59
60         FD_ZERO(&in);
61         FD_ZERO(&out);
62         FD_ZERO(&except);
63         timeout = 0; /* hang on select */
64         max = 0;
65         for (p = iochans; p; p = p->next)
66         {
67             if (p->force_event)
68                 timeout = &nullto;
69             if (p->flags & EVENT_INPUT)
70                 FD_SET(p->fd, &in);
71             if (p->flags & EVENT_OUTPUT)
72                 FD_SET(p->fd, &out);
73             if (p->flags & EVENT_EXCEPT)
74                 FD_SET(p->fd, &except);
75             if (p->fd > max)
76                 max = p->fd;
77         }
78         if ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
79         {
80             if (errno == EINTR)
81                 continue;
82             return 1;
83         }
84         for (p = iochans; p; p = nextp)
85         {
86             int force_event = p->force_event;
87
88             p->force_event = 0;
89             nextp = p->next;
90             if (FD_ISSET(p->fd, &in) || force_event == EVENT_INPUT)
91                 (*p->fun)(p, EVENT_INPUT);
92             if (!p->destroyed && (FD_ISSET(p->fd, &out) ||
93                  force_event == EVENT_OUTPUT))
94                 (*p->fun)(p, EVENT_OUTPUT);
95             if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
96                 force_event == EVENT_EXCEPT))
97                 (*p->fun)(p, EVENT_EXCEPT);
98             if (p->destroyed)
99             {
100                 IOCHAN tmp = p, pr;
101
102                 if (p == iochans)
103                     iochans = p->next;
104                 else
105                 {
106                     for (pr = iochans; pr; pr = pr->next)
107                         if (pr->next == p)
108                             break;
109                     assert(pr);
110                     pr->next = p->next;
111                 }
112                 if (nextp == p)
113                     nextp = p->next;
114                 free(tmp);
115             }
116         }
117     }
118     while (iochans);
119     return 0;
120 }