2 * Copyright (C) 1995-2007, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: zoom-socket.c,v 1.4 2007-05-06 20:12:20 adam Exp $
9 * \brief Implements ZOOM C socket interface.
18 #include <yaz/xmalloc.h>
21 #include <sys/types.h>
30 #include <sys/select.h>
34 #define FD_SETSIZE 512
41 * Note that ZOOM_event_sys_select() is limited as to how many file
42 * descriptors it can multiplex due to its use of select() which in
43 * turn uses the statically defined fd_set type to be a bitmap of the
44 * file descriptors to check. On Ubuntu 6.06 (and almost certainly on
45 * Debian, and probably on all Linuxes, and maybe all Unixes) this is
46 * by default set to 1024 (though it may be possible to override this
47 * using a #define before including <sys/select.h> -- I've not tried
48 * this). 1024 file descriptors is a lot, but not enough in all
49 * cases, e.g. when running IRSpy on a large target database. So you
50 * should ensure that YAZ uses ZOOM_event_sys_poll() when possible.
53 ZOOM_event_sys_select(int no, ZOOM_connection *cs)
56 fd_set input, output, except;
66 for (i = 0; i<no; i++)
68 ZOOM_connection c = cs[i];
73 fd = ZOOM_connection_get_socket(c);
74 mask = ZOOM_connection_get_mask(c);
75 timeout = ZOOM_connection_get_timeout(c);
82 if (mask & ZOOM_SELECT_READ)
84 if (mask & ZOOM_SELECT_WRITE)
86 if (mask & ZOOM_SELECT_EXCEPT)
97 while ((r = select(max_fd+1, &input, &output, &except,
98 (timeout == -1 ? 0 : &tv))) < 0 && errno == EINTR)
104 yaz_log(YLOG_WARN|YLOG_ERRNO, "ZOOM_event_sys_select");
108 for (i = 0; i<no; i++)
110 ZOOM_connection c = cs[i];
115 fd = ZOOM_connection_get_socket(c);
119 /* no timeout and real socket */
120 if (FD_ISSET(fd, &input))
121 mask += ZOOM_SELECT_READ;
122 if (FD_ISSET(fd, &output))
123 mask += ZOOM_SELECT_WRITE;
124 if (FD_ISSET(fd, &except))
125 mask += ZOOM_SELECT_EXCEPT;
127 ZOOM_connection_fire_event_socket(c, mask);
130 ZOOM_connection_fire_event_timeout(c);
137 ZOOM_event_sys_poll(int no, ZOOM_connection *cs)
139 struct pollfd *pollfds = (struct pollfd *) xmalloc(no * sizeof *pollfds);
140 ZOOM_connection *poll_cs = (ZOOM_connection *)
141 xmalloc(no * sizeof *poll_cs);
146 for (i = 0; i<no; i++)
148 ZOOM_connection c = cs[i];
153 fd = ZOOM_connection_get_socket(c);
154 mask = ZOOM_connection_get_mask(c);
155 timeout = ZOOM_connection_get_timeout(c);
161 short poll_events = 0;
163 if (mask & ZOOM_SELECT_READ)
164 poll_events += POLLIN;
165 if (mask & ZOOM_SELECT_WRITE)
166 poll_events += POLLOUT;
167 if (mask & ZOOM_SELECT_EXCEPT)
168 poll_events += POLLERR;
169 pollfds[nfds].fd = fd;
170 pollfds[nfds].events = poll_events;
171 pollfds[nfds].revents = 0;
181 while ((r = poll(pollfds, nfds,
182 (timeout == -1 ? -1 : timeout * 1000))) < 0
189 yaz_log(YLOG_WARN|YLOG_ERRNO, "ZOOM_event_sys_poll");
194 for (i = 0; i<nfds; i++)
196 ZOOM_connection c = poll_cs[i];
200 if (pollfds[i].revents & POLLIN)
201 mask += ZOOM_SELECT_READ;
202 if (pollfds[i].revents & POLLOUT)
203 mask += ZOOM_SELECT_WRITE;
204 if (pollfds[i].revents & POLLERR)
205 mask += ZOOM_SELECT_EXCEPT;
206 ZOOM_connection_fire_event_socket(c, mask);
209 ZOOM_connection_fire_event_timeout(c);
218 ZOOM_event(int no, ZOOM_connection *cs)
222 r = ZOOM_event_nonblock(no, cs);
226 ZOOM_event_sys_poll(no, cs);
228 ZOOM_event_sys_select(no, cs);
230 return ZOOM_event_nonblock(no, cs);
236 * indent-tabs-mode: nil
238 * vim: shiftwidth=4 tabstop=8 expandtab