source: trunk/gsdl/packages/yaz/server/eventl.c@ 1343

Last change on this file since 1343 was 1343, checked in by johnmcp, 24 years ago

Added the YAZ toolkit source to the packages directory (for z39.50 stuff)

  • Property svn:keywords set to Author Date Id Revision
File size: 6.2 KB
Line 
1/*
2 * Copyright (c) 1995-1999, Index Data
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
5 *
6 * $Log$
7 * Revision 1.1 2000/08/03 03:11:40 johnmcp
8 * Added the YAZ toolkit source to the packages directory (for z39.50 stuff)
9 *
10 * Revision 1.29 1999/11/30 13:47:12 adam
11 * Improved installation. Moved header files to include/yaz.
12 *
13 * Revision 1.28 1999/08/27 09:40:32 adam
14 * Renamed logf function to yaz_log. Removed VC++ project files.
15 *
16 * Revision 1.27 1999/02/02 13:57:34 adam
17 * Uses preprocessor define WIN32 instead of WINDOWS to build code
18 * for Microsoft WIN32.
19 *
20 * Revision 1.26 1998/02/11 11:53:35 adam
21 * Changed code so that it compiles as C++.
22 *
23 * Revision 1.25 1998/01/29 13:30:23 adam
24 * Better event handle system for NT/Unix.
25 *
26 * Revision 1.24 1997/09/04 14:19:13 adam
27 * Added credits.
28 *
29 * Revision 1.23 1997/09/01 08:52:59 adam
30 * New windows NT/95 port using MSV5.0. The test server 'ztest' was
31 * moved a separate directory. MSV5.0 project server.dsp created.
32 * As an option, the server can now operate as an NT service.
33 *
34 * Revision 1.22 1996/07/06 19:58:35 quinn
35 * System headerfiles gathered in yconfig
36 *
37 * Revision 1.21 1996/02/21 12:55:51 quinn
38 * small
39 *
40 * Revision 1.20 1996/02/21 12:52:55 quinn
41 * Test
42 *
43 * Revision 1.19 1995/12/05 11:17:30 quinn
44 * Moved some paranthesises around. Sigh.
45 *
46 * Revision 1.18 1995/11/13 09:27:41 quinn
47 * Fiddling with the variant stuff.
48 *
49 * Revision 1.17 1995/11/07 12:37:44 quinn
50 * Added support for forcing TIMEOUT event.
51 *
52 * Revision 1.16 1995/11/01 13:54:56 quinn
53 * Minor adjustments
54 *
55 * Revision 1.15 1995/09/15 14:44:15 quinn
56 * *** empty log message ***
57 *
58 * Revision 1.14 1995/08/29 14:44:50 quinn
59 * Reset timeouts.
60 *
61 * Revision 1.13 1995/08/29 11:17:56 quinn
62 * Added code to receive close
63 *
64 * Revision 1.12 1995/08/29 10:41:18 quinn
65 * Small.
66 *
67 * Revision 1.11 1995/06/19 12:39:09 quinn
68 * Fixed bug in timeout code. Added BER dumper.
69 *
70 * Revision 1.10 1995/06/16 10:31:33 quinn
71 * Added session timeout.
72 *
73 * Revision 1.9 1995/06/05 10:53:31 quinn
74 * Added a better SCAN.
75 *
76 * Revision 1.8 1995/05/16 08:51:01 quinn
77 * License, documentation, and memory fixes
78 *
79 * Revision 1.7 1995/03/27 15:02:01 quinn
80 * Added some includes for better portability
81 *
82 * Revision 1.6 1995/03/27 08:34:21 quinn
83 * Added dynamic server functionality.
84 * Released bindings to session.c (is now redundant)
85 *
86 * Revision 1.5 1995/03/15 08:37:41 quinn
87 * Now we're pretty much set for nonblocking I/O.
88 *
89 * Revision 1.4 1995/03/14 16:59:48 quinn
90 * Bug-fixes
91 *
92 * Revision 1.3 1995/03/14 11:30:14 quinn
93 * Works better now.
94 *
95 * Revision 1.2 1995/03/14 10:27:59 quinn
96 * More work on demo server.
97 *
98 * Revision 1.1 1995/03/10 18:22:44 quinn
99 * The rudiments of an asynchronous server.
100 *
101 */
102
103#include <stdio.h>
104#include <assert.h>
105#ifdef WIN32
106#include <winsock.h>
107#else
108#include <unistd.h>
109#endif
110#include <stdlib.h>
111#include <errno.h>
112#include <string.h>
113
114#include <yaz/yconfig.h>
115#include <yaz/log.h>
116#include <yaz/comstack.h>
117#include <yaz/xmalloc.h>
118#include "eventl.h"
119#include "session.h"
120#include <yaz/statserv.h>
121
122IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags)
123{
124 IOCHAN new_iochan;
125
126 if (!(new_iochan = (IOCHAN)xmalloc(sizeof(*new_iochan))))
127 return 0;
128 new_iochan->destroyed = 0;
129 new_iochan->fd = fd;
130 new_iochan->flags = flags;
131 new_iochan->fun = cb;
132 new_iochan->force_event = 0;
133 new_iochan->last_event = new_iochan->max_idle = 0;
134 new_iochan->next = NULL;
135 return new_iochan;
136}
137
138int event_loop(IOCHAN *iochans)
139{
140 do /* loop as long as there are active associations to process */
141 {
142 IOCHAN p, nextp;
143 fd_set in, out, except;
144 int res, max;
145 static struct timeval nullto = {0, 0}, to;
146 struct timeval *timeout;
147
148 FD_ZERO(&in);
149 FD_ZERO(&out);
150 FD_ZERO(&except);
151 timeout = &to; /* hang on select */
152 to.tv_sec = 5*60;
153 to.tv_usec = 0;
154 max = 0;
155 for (p = *iochans; p; p = p->next)
156 {
157 if (p->force_event)
158 timeout = &nullto; /* polling select */
159 if (p->flags & EVENT_INPUT)
160 FD_SET(p->fd, &in);
161 if (p->flags & EVENT_OUTPUT)
162 FD_SET(p->fd, &out);
163 if (p->flags & EVENT_EXCEPT)
164 FD_SET(p->fd, &except);
165 if (p->fd > max)
166 max = p->fd;
167 }
168 if ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
169 {
170 if (errno == EINTR)
171 continue;
172 else
173 {
174 /* Destroy the first member in the chain, and try again */
175 association *assoc = (association *)iochan_getdata(*iochans);
176 COMSTACK conn = assoc->client_link;
177
178 cs_close(conn);
179 destroy_association(assoc);
180 iochan_destroy(*iochans);
181 yaz_log(LOG_DEBUG, "error select, destroying iochan %p",
182 *iochans);
183 }
184 }
185 for (p = *iochans; p; p = p->next)
186 {
187 int force_event = p->force_event;
188 time_t now = time(0);
189
190 p->force_event = 0;
191 if (!p->destroyed && (FD_ISSET(p->fd, &in) ||
192 force_event == EVENT_INPUT))
193 {
194 p->last_event = now;
195 (*p->fun)(p, EVENT_INPUT);
196 }
197 if (!p->destroyed && (FD_ISSET(p->fd, &out) ||
198 force_event == EVENT_OUTPUT))
199 {
200 p->last_event = now;
201 (*p->fun)(p, EVENT_OUTPUT);
202 }
203 if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
204 force_event == EVENT_EXCEPT))
205 {
206 p->last_event = now;
207 (*p->fun)(p, EVENT_EXCEPT);
208 }
209 if (!p->destroyed && ((p->max_idle && now - p->last_event >
210 p->max_idle) || force_event == EVENT_TIMEOUT))
211 {
212 p->last_event = now;
213 (*p->fun)(p, EVENT_TIMEOUT);
214 }
215 }
216 for (p = *iochans; p; p = nextp)
217 {
218 nextp = p->next;
219
220 if (p->destroyed)
221 {
222 IOCHAN tmp = p, pr;
223
224 /* We need to inform the threadlist that this channel has been destroyed */
225 statserv_remove(p);
226
227 /* Now reset the pointers */
228 if (p == *iochans)
229 *iochans = p->next;
230 else
231 {
232 for (pr = *iochans; pr; pr = pr->next)
233 if (pr->next == p)
234 break;
235 assert(pr); /* grave error if it weren't there */
236 pr->next = p->next;
237 }
238 if (nextp == p)
239 nextp = p->next;
240 xfree(tmp);
241 }
242 }
243 }
244 while (*iochans);
245 return 0;
246}
Note: See TracBrowser for help on using the repository browser.