2 * Copyright (c) 1995-1997, Index Data
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.24 1997-09-04 14:19:13 adam
10 * Revision 1.23 1997/09/01 08:52:59 adam
11 * New windows NT/95 port using MSV5.0. The test server 'ztest' was
12 * moved a separate directory. MSV5.0 project server.dsp created.
13 * As an option, the server can now operate as an NT service.
15 * Revision 1.22 1996/07/06 19:58:35 quinn
16 * System headerfiles gathered in yconfig
18 * Revision 1.21 1996/02/21 12:55:51 quinn
21 * Revision 1.20 1996/02/21 12:52:55 quinn
24 * Revision 1.19 1995/12/05 11:17:30 quinn
25 * Moved some paranthesises around. Sigh.
27 * Revision 1.18 1995/11/13 09:27:41 quinn
28 * Fiddling with the variant stuff.
30 * Revision 1.17 1995/11/07 12:37:44 quinn
31 * Added support for forcing TIMEOUT event.
33 * Revision 1.16 1995/11/01 13:54:56 quinn
36 * Revision 1.15 1995/09/15 14:44:15 quinn
37 * *** empty log message ***
39 * Revision 1.14 1995/08/29 14:44:50 quinn
42 * Revision 1.13 1995/08/29 11:17:56 quinn
43 * Added code to receive close
45 * Revision 1.12 1995/08/29 10:41:18 quinn
48 * Revision 1.11 1995/06/19 12:39:09 quinn
49 * Fixed bug in timeout code. Added BER dumper.
51 * Revision 1.10 1995/06/16 10:31:33 quinn
52 * Added session timeout.
54 * Revision 1.9 1995/06/05 10:53:31 quinn
55 * Added a better SCAN.
57 * Revision 1.8 1995/05/16 08:51:01 quinn
58 * License, documentation, and memory fixes
60 * Revision 1.7 1995/03/27 15:02:01 quinn
61 * Added some includes for better portability
63 * Revision 1.6 1995/03/27 08:34:21 quinn
64 * Added dynamic server functionality.
65 * Released bindings to session.c (is now redundant)
67 * Revision 1.5 1995/03/15 08:37:41 quinn
68 * Now we're pretty much set for nonblocking I/O.
70 * Revision 1.4 1995/03/14 16:59:48 quinn
73 * Revision 1.3 1995/03/14 11:30:14 quinn
76 * Revision 1.2 1995/03/14 10:27:59 quinn
77 * More work on demo server.
79 * Revision 1.1 1995/03/10 18:22:44 quinn
80 * The rudiments of an asynchronous server.
100 #include "statserv.h"
105 static IOCHAN iochans = 0;
107 IOCHAN iochan_getchan(void)
114 IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags)
118 if (!(new_iochan = xmalloc(sizeof(*new_iochan))))
120 new_iochan->destroyed = 0;
122 new_iochan->flags = flags;
123 new_iochan->fun = cb;
124 new_iochan->force_event = 0;
125 new_iochan->last_event = new_iochan->max_idle = 0;
128 /* For windows we don't have a linklist of iochans */
129 new_iochan->next = NULL;
131 new_iochan->next = iochans;
132 iochans = new_iochan;
138 /* Event loop now takes an iochan as a parameter */
140 int __stdcall event_loop(IOCHAN iochans)
142 int event_loop(IOCHAN dummylistener)
145 do /* loop as long as there are active associations to process */
148 fd_set in, out, except;
150 static struct timeval nullto = {0, 0}, to;
151 struct timeval *timeout;
156 timeout = &to; /* hang on select */
160 for (p = iochans; p; p = p->next)
163 timeout = &nullto; /* polling select */
164 if (p->flags & EVENT_INPUT)
166 if (p->flags & EVENT_OUTPUT)
168 if (p->flags & EVENT_EXCEPT)
169 FD_SET(p->fd, &except);
173 if ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
179 /* Destroy the first member in the chain, and try again */
180 association *assoc = iochan_getdata(iochans);
181 COMSTACK conn = assoc->client_link;
184 destroy_association(assoc);
185 iochan_destroy(iochans);
186 logf(LOG_DEBUG, "error while selecting, destroying iochan %p", iochans);
189 for (p = iochans; p; p = p->next)
191 int force_event = p->force_event;
192 time_t now = time(0);
195 if (!p->destroyed && (FD_ISSET(p->fd, &in) || force_event == EVENT_INPUT))
198 (*p->fun)(p, EVENT_INPUT);
200 if (!p->destroyed && (FD_ISSET(p->fd, &out) ||
201 force_event == EVENT_OUTPUT))
204 (*p->fun)(p, EVENT_OUTPUT);
206 if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
207 force_event == EVENT_EXCEPT))
210 (*p->fun)(p, EVENT_EXCEPT);
212 if (!p->destroyed && ((p->max_idle && now - p->last_event >
213 p->max_idle) || force_event == EVENT_TIMEOUT))
216 (*p->fun)(p, EVENT_TIMEOUT);
219 for (p = iochans; p; p = nextp)
227 /* We need to inform the threadlist that this channel has been destroyed */
230 /* Now reset the pointers */
235 for (pr = iochans; pr; pr = pr->next)
238 assert(pr); /* grave error if it weren't there */