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