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