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