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