YAZ 5.35.1
poll.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
9#if HAVE_CONFIG_H
10#include <config.h>
11#endif
12
13#include <assert.h>
14#include <string.h>
15#include <errno.h>
16
17#include <yaz/log.h>
18#include <yaz/xmalloc.h>
19#include <yaz/poll.h>
20
21#if HAVE_SYS_TYPES_H
22#include <sys/types.h>
23#endif
24#if HAVE_SYS_TIME_H
25#include <sys/time.h>
26#endif
27#if HAVE_SYS_POLL_H
28#include <sys/poll.h>
29#endif
30#if HAVE_SYS_SELECT_H
31#include <sys/select.h>
32#endif
33#ifdef WIN32
34#if FD_SETSIZE < 512
35#define FD_SETSIZE 512
36#endif
37#include <winsock.h>
38#endif
39
40/*
41 Note that yaz_poll_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_yaz_poll_poll() when possible.
51*/
52int yaz_poll_select(struct yaz_poll_fd *fds, int num_fds, int sec, int nsec)
53{
54 struct timeval tv;
55 fd_set input, output, except;
56 int i, r;
57 int max_fd = 0;
58
59 FD_ZERO(&input);
60 FD_ZERO(&output);
61 FD_ZERO(&except);
62
63 assert(num_fds >= 0);
64 for (i = 0; i < num_fds; i++)
65 {
66 enum yaz_poll_mask mask = fds[i].input_mask;
67 int fd = fds[i].fd;
68
69 /* Timeout events */
70 if (fd < 0)
71 continue;
72
73 if (mask & yaz_poll_read)
74 FD_SET(fd, &input);
75 if (mask & yaz_poll_write)
76 FD_SET(fd, &output);
78 FD_SET(fd, &except);
79 if (max_fd < fd)
80 max_fd = fd;
81 }
82 tv.tv_sec = sec;
83 tv.tv_usec = nsec / 1000;
84
85 r = select(max_fd+1, &input, &output, &except, (sec == -1 ? 0 : &tv));
86 if (r >= 0)
87 {
88 for (i = 0; i < num_fds; i++)
89 {
91 int fd = fds[i].fd;
92 if (!r)
94 else if (fd >= 0) {
95 if (FD_ISSET(fd, &input))
97 if (FD_ISSET(fd, &output))
99 if (FD_ISSET(fd, &except))
101 }
102 fds[i].output_mask = mask;
103 }
104 }
105 return r;
106}
107
108#if HAVE_SYS_POLL_H
109int yaz_poll_poll(struct yaz_poll_fd *fds, int num_fds, int sec, int nsec)
110{
111 int i, r;
112 struct pollfd *pollfds = 0;
113
114 if (num_fds > 0)
115 pollfds = (struct pollfd *) xmalloc(num_fds * sizeof *pollfds);
116
117 assert(num_fds >= 0);
118 for (i = 0; i < num_fds; i++)
119 {
120 enum yaz_poll_mask mask = fds[i].input_mask;
121 int fd = fds[i].fd;
122 short poll_events = 0;
123
124 if (mask & yaz_poll_read)
125 poll_events += POLLIN;
126 if (mask & yaz_poll_write)
127 poll_events += POLLOUT;
128 if (mask & yaz_poll_except)
129 poll_events += POLLERR;
130 pollfds[i].fd = fd;
131 pollfds[i].events = poll_events;
132 pollfds[i].revents = 0;
133 }
134 r = poll(pollfds, num_fds, sec == -1 ? -1 : sec*1000 + nsec/1000000);
135 if (r >= 0)
136 {
137 for (i = 0; i < num_fds; i++)
138 {
140 if (!r)
142 else
143 {
144 if (pollfds[i].revents & POLLIN)
146 if (pollfds[i].revents & POLLOUT)
148 if (pollfds[i].revents & ~(POLLIN | POLLOUT))
149 {
151 }
152 }
153 fds[i].output_mask = mask;
154 }
155 }
156 xfree(pollfds);
157 return r;
158}
159#endif
160
161int yaz_poll(struct yaz_poll_fd *fds, int num_fds, int sec, int nsec)
162{
163#if HAVE_SYS_POLL_H
164 return yaz_poll_poll(fds, num_fds, sec, nsec);
165#else
166 return yaz_poll_select(fds, num_fds, sec, nsec);
167#endif
168}
169
170/*
171 * Local variables:
172 * c-basic-offset: 4
173 * c-file-style: "Stroustrup"
174 * indent-tabs-mode: nil
175 * End:
176 * vim: shiftwidth=4 tabstop=8 expandtab
177 */
178
Header for errno utilities.
int mask
Definition log.c:83
Logging utility.
int yaz_poll(struct yaz_poll_fd *fds, int num_fds, int sec, int nsec)
poll wrapper for poll or select
Definition poll.c:161
int yaz_poll_select(struct yaz_poll_fd *fds, int num_fds, int sec, int nsec)
Definition poll.c:52
Poll, select wrappers.
#define yaz_poll_add(var, value)
Definition poll.h:76
yaz_poll_mask
select/poll masks .. timeout is "output" only
Definition poll.h:41
@ yaz_poll_read
Definition poll.h:43
@ yaz_poll_except
Definition poll.h:45
@ yaz_poll_none
Definition poll.h:42
@ yaz_poll_write
Definition poll.h:44
@ yaz_poll_timeout
Definition poll.h:46
select/poll fd info
Definition poll.h:50
enum yaz_poll_mask output_mask
Definition poll.h:54
enum yaz_poll_mask input_mask
Definition poll.h:52
int fd
Definition poll.h:56
Header for memory handling functions.
#define xfree(x)
utility macro which calls xfree_f
Definition xmalloc.h:53
#define xmalloc(x)
utility macro which calls malloc_f
Definition xmalloc.h:49