YAZ  5.34.0
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 */
52 int 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);
77  if (mask & yaz_poll_except)
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
109 int 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 
161 int 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