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