socket_poller.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 
3 #include "precompiled.hpp"
4 #include "socket_poller.hpp"
5 #include "err.hpp"
6 #include "polling_util.hpp"
7 #include "macros.hpp"
8 
9 #include <limits.h>
10 
11 static bool is_thread_safe (const zmq::socket_base_t &socket_)
12 {
13  // do not use getsockopt here, since that would fail during context termination
14  return socket_.is_thread_safe ();
15 }
16 
17 // compare elements to value
18 template <class It, class T, class Pred>
19 static It find_if2 (It b_, It e_, const T &value, Pred pred)
20 {
21  for (; b_ != e_; ++b_) {
22  if (pred (*b_, value)) {
23  break;
24  }
25  }
26  return b_;
27 }
28 
30  _tag (0xCAFEBABE),
31  _signaler (NULL)
32 #if defined ZMQ_POLL_BASED_ON_POLL
33  ,
34  _pollfds (NULL)
35 #elif defined ZMQ_POLL_BASED_ON_SELECT
36  ,
37  _max_fd (0)
38 #endif
39 {
40  rebuild ();
41 }
42 
44 {
45  // Mark the socket_poller as dead
46  _tag = 0xdeadbeef;
47 
48  for (items_t::iterator it = _items.begin (), end = _items.end (); it != end;
49  ++it) {
50  // TODO shouldn't this zmq_assert (it->socket->check_tag ()) instead?
51  if (it->socket && it->socket->check_tag ()
52  && is_thread_safe (*it->socket)) {
53  it->socket->remove_signaler (_signaler);
54  }
55  }
56 
57  if (_signaler != NULL) {
58  LIBZMQ_DELETE (_signaler);
59  }
60 
61 #if defined ZMQ_POLL_BASED_ON_POLL
62  if (_pollfds) {
63  free (_pollfds);
64  _pollfds = NULL;
65  }
66 #endif
67 }
68 
70 {
71  return _tag == 0xCAFEBABE;
72 }
73 
75 {
76  if (_signaler) {
77  *fd_ = _signaler->get_fd ();
78  return 0;
79  }
80  // Only thread-safe socket types are guaranteed to have a signaler.
81  errno = EINVAL;
82  return -1;
83 }
84 
86  void *user_data_,
87  short events_)
88 {
89  if (find_if2 (_items.begin (), _items.end (), socket_, &is_socket)
90  != _items.end ()) {
91  errno = EINVAL;
92  return -1;
93  }
94 
95  if (is_thread_safe (*socket_)) {
96  if (_signaler == NULL) {
97  _signaler = new (std::nothrow) signaler_t ();
98  if (!_signaler) {
99  errno = ENOMEM;
100  return -1;
101  }
102  if (!_signaler->valid ()) {
103  delete _signaler;
104  _signaler = NULL;
105  errno = EMFILE;
106  return -1;
107  }
108  }
109 
110  socket_->add_signaler (_signaler);
111  }
112 
113  const item_t item = {
114  socket_,
115  0,
116  user_data_,
117  events_
118 #if defined ZMQ_POLL_BASED_ON_POLL
119  ,
120  -1
121 #endif
122  };
123  try {
124  _items.push_back (item);
125  }
126  catch (const std::bad_alloc &) {
127  errno = ENOMEM;
128  return -1;
129  }
130  _need_rebuild = true;
131 
132  return 0;
133 }
134 
135 int zmq::socket_poller_t::add_fd (fd_t fd_, void *user_data_, short events_)
136 {
137  if (find_if2 (_items.begin (), _items.end (), fd_, &is_fd)
138  != _items.end ()) {
139  errno = EINVAL;
140  return -1;
141  }
142 
143  const item_t item = {
144  NULL,
145  fd_,
146  user_data_,
147  events_
148 #if defined ZMQ_POLL_BASED_ON_POLL
149  ,
150  -1
151 #endif
152  };
153  try {
154  _items.push_back (item);
155  }
156  catch (const std::bad_alloc &) {
157  errno = ENOMEM;
158  return -1;
159  }
160  _need_rebuild = true;
161 
162  return 0;
163 }
164 
165 int zmq::socket_poller_t::modify (const socket_base_t *socket_, short events_)
166 {
167  const items_t::iterator it =
168  find_if2 (_items.begin (), _items.end (), socket_, &is_socket);
169 
170  if (it == _items.end ()) {
171  errno = EINVAL;
172  return -1;
173  }
174 
175  it->events = events_;
176  _need_rebuild = true;
177 
178  return 0;
179 }
180 
181 
182 int zmq::socket_poller_t::modify_fd (fd_t fd_, short events_)
183 {
184  const items_t::iterator it =
185  find_if2 (_items.begin (), _items.end (), fd_, &is_fd);
186 
187  if (it == _items.end ()) {
188  errno = EINVAL;
189  return -1;
190  }
191 
192  it->events = events_;
193  _need_rebuild = true;
194 
195  return 0;
196 }
197 
198 
200 {
201  const items_t::iterator it =
202  find_if2 (_items.begin (), _items.end (), socket_, &is_socket);
203 
204  if (it == _items.end ()) {
205  errno = EINVAL;
206  return -1;
207  }
208 
209  _items.erase (it);
210  _need_rebuild = true;
211 
212  if (is_thread_safe (*socket_)) {
213  socket_->remove_signaler (_signaler);
214  }
215 
216  return 0;
217 }
218 
220 {
221  const items_t::iterator it =
222  find_if2 (_items.begin (), _items.end (), fd_, &is_fd);
223 
224  if (it == _items.end ()) {
225  errno = EINVAL;
226  return -1;
227  }
228 
229  _items.erase (it);
230  _need_rebuild = true;
231 
232  return 0;
233 }
234 
236 {
237  _use_signaler = false;
238  _pollset_size = 0;
239  _need_rebuild = false;
240 
241 #if defined ZMQ_POLL_BASED_ON_POLL
242 
243  if (_pollfds) {
244  free (_pollfds);
245  _pollfds = NULL;
246  }
247 
248  for (items_t::iterator it = _items.begin (), end = _items.end (); it != end;
249  ++it) {
250  if (it->events) {
251  if (it->socket && is_thread_safe (*it->socket)) {
252  if (!_use_signaler) {
253  _use_signaler = true;
254  _pollset_size++;
255  }
256  } else
257  _pollset_size++;
258  }
259  }
260 
261  if (_pollset_size == 0)
262  return 0;
263 
264  _pollfds = static_cast<pollfd *> (malloc (_pollset_size * sizeof (pollfd)));
265 
266  if (!_pollfds) {
267  errno = ENOMEM;
268  _need_rebuild = true;
269  return -1;
270  }
271 
272  int item_nbr = 0;
273 
274  if (_use_signaler) {
275  item_nbr = 1;
276  _pollfds[0].fd = _signaler->get_fd ();
277  _pollfds[0].events = POLLIN;
278  }
279 
280  for (items_t::iterator it = _items.begin (), end = _items.end (); it != end;
281  ++it) {
282  if (it->events) {
283  if (it->socket) {
284  if (!is_thread_safe (*it->socket)) {
285  size_t fd_size = sizeof (zmq::fd_t);
286  const int rc = it->socket->getsockopt (
287  ZMQ_FD, &_pollfds[item_nbr].fd, &fd_size);
288  zmq_assert (rc == 0);
289 
290  _pollfds[item_nbr].events = POLLIN;
291  item_nbr++;
292  }
293  } else {
294  _pollfds[item_nbr].fd = it->fd;
295  _pollfds[item_nbr].events =
296  (it->events & ZMQ_POLLIN ? POLLIN : 0)
297  | (it->events & ZMQ_POLLOUT ? POLLOUT : 0)
298  | (it->events & ZMQ_POLLPRI ? POLLPRI : 0);
299  it->pollfd_index = item_nbr;
300  item_nbr++;
301  }
302  }
303  }
304 
305 #elif defined ZMQ_POLL_BASED_ON_SELECT
306 
307  // Ensure we do not attempt to select () on more than FD_SETSIZE
308  // file descriptors.
309  zmq_assert (_items.size () <= FD_SETSIZE);
310 
311  _pollset_in.resize (_items.size ());
312  _pollset_out.resize (_items.size ());
313  _pollset_err.resize (_items.size ());
314 
315  FD_ZERO (_pollset_in.get ());
316  FD_ZERO (_pollset_out.get ());
317  FD_ZERO (_pollset_err.get ());
318 
319  for (items_t::iterator it = _items.begin (), end = _items.end (); it != end;
320  ++it) {
321  if (it->socket && is_thread_safe (*it->socket) && it->events) {
322  _use_signaler = true;
323  FD_SET (_signaler->get_fd (), _pollset_in.get ());
324  _pollset_size = 1;
325  break;
326  }
327  }
328 
329  _max_fd = 0;
330 
331  // Build the fd_sets for passing to select ().
332  for (items_t::iterator it = _items.begin (), end = _items.end (); it != end;
333  ++it) {
334  if (it->events) {
335  // If the poll item is a 0MQ socket we are interested in input on the
336  // notification file descriptor retrieved by the ZMQ_FD socket option.
337  if (it->socket) {
338  if (!is_thread_safe (*it->socket)) {
339  zmq::fd_t notify_fd;
340  size_t fd_size = sizeof (zmq::fd_t);
341  int rc =
342  it->socket->getsockopt (ZMQ_FD, &notify_fd, &fd_size);
343  zmq_assert (rc == 0);
344 
345  FD_SET (notify_fd, _pollset_in.get ());
346  if (_max_fd < notify_fd)
347  _max_fd = notify_fd;
348 
349  _pollset_size++;
350  }
351  }
352  // Else, the poll item is a raw file descriptor. Convert the poll item
353  // events to the appropriate fd_sets.
354  else {
355  if (it->events & ZMQ_POLLIN)
356  FD_SET (it->fd, _pollset_in.get ());
357  if (it->events & ZMQ_POLLOUT)
358  FD_SET (it->fd, _pollset_out.get ());
359  if (it->events & ZMQ_POLLERR)
360  FD_SET (it->fd, _pollset_err.get ());
361  if (_max_fd < it->fd)
362  _max_fd = it->fd;
363 
364  _pollset_size++;
365  }
366  }
367  }
368 
369 #endif
370 
371  return 0;
372 }
373 
375  zmq::socket_poller_t::event_t *events_, int n_events_, int found_)
376 {
377  for (int i = found_; i < n_events_; ++i) {
378  events_[i].socket = NULL;
379  events_[i].fd = zmq::retired_fd;
380  events_[i].user_data = NULL;
381  events_[i].events = 0;
382  }
383 }
384 
385 #if defined ZMQ_POLL_BASED_ON_POLL
387  int n_events_)
388 #elif defined ZMQ_POLL_BASED_ON_SELECT
390  int n_events_,
391  fd_set &inset_,
392  fd_set &outset_,
393  fd_set &errset_)
394 #endif
395 {
396  int found = 0;
397  for (items_t::iterator it = _items.begin (), end = _items.end ();
398  it != end && found < n_events_; ++it) {
399  // The poll item is a 0MQ socket. Retrieve pending events
400  // using the ZMQ_EVENTS socket option.
401  if (it->socket) {
402  size_t events_size = sizeof (uint32_t);
403  uint32_t events;
404  if (it->socket->getsockopt (ZMQ_EVENTS, &events, &events_size)
405  == -1) {
406  return -1;
407  }
408 
409  if (it->events & events) {
410  events_[found].socket = it->socket;
411  events_[found].fd = zmq::retired_fd;
412  events_[found].user_data = it->user_data;
413  events_[found].events = it->events & events;
414  ++found;
415  }
416  }
417  // Else, the poll item is a raw file descriptor, simply convert
418  // the events to zmq_pollitem_t-style format.
419  else if (it->events) {
420 #if defined ZMQ_POLL_BASED_ON_POLL
421  zmq_assert (it->pollfd_index >= 0);
422  const short revents = _pollfds[it->pollfd_index].revents;
423  short events = 0;
424 
425  if (revents & POLLIN)
426  events |= ZMQ_POLLIN;
427  if (revents & POLLOUT)
428  events |= ZMQ_POLLOUT;
429  if (revents & POLLPRI)
430  events |= ZMQ_POLLPRI;
431  if (revents & ~(POLLIN | POLLOUT | POLLPRI))
432  events |= ZMQ_POLLERR;
433 
434 #elif defined ZMQ_POLL_BASED_ON_SELECT
435 
436  short events = 0;
437 
438  if (FD_ISSET (it->fd, &inset_))
439  events |= ZMQ_POLLIN;
440  if (FD_ISSET (it->fd, &outset_))
441  events |= ZMQ_POLLOUT;
442  if (FD_ISSET (it->fd, &errset_))
443  events |= ZMQ_POLLERR;
444 #endif //POLL_SELECT
445 
446  if (events) {
447  events_[found].socket = NULL;
448  events_[found].fd = it->fd;
449  events_[found].user_data = it->user_data;
450  events_[found].events = events;
451  ++found;
452  }
453  }
454  }
455 
456  return found;
457 }
458 
459 //Return 0 if timeout is expired otherwise 1
461  long timeout_,
462  uint64_t &now_,
463  uint64_t &end_,
464  bool &first_pass_)
465 {
466  // If socket_poller_t::timeout is zero, exit immediately whether there
467  // are events or not.
468  if (timeout_ == 0)
469  return 0;
470 
471  // At this point we are meant to wait for events but there are none.
472  // If timeout is infinite we can just loop until we get some events.
473  if (timeout_ < 0) {
474  if (first_pass_)
475  first_pass_ = false;
476  return 1;
477  }
478 
479  // The timeout is finite and there are no events. In the first pass
480  // we get a timestamp of when the polling have begun. (We assume that
481  // first pass have taken negligible time). We also compute the time
482  // when the polling should time out.
483  now_ = clock_.now_ms ();
484  if (first_pass_) {
485  end_ = now_ + timeout_;
486  first_pass_ = false;
487  return 1;
488  }
489 
490  // Find out whether timeout have expired.
491  if (now_ >= end_)
492  return 0;
493 
494  return 1;
495 }
496 
498  int n_events_,
499  long timeout_)
500 {
501  if (_items.empty () && timeout_ < 0) {
502  errno = EFAULT;
503  return -1;
504  }
505 
506  if (_need_rebuild) {
507  const int rc = rebuild ();
508  if (rc == -1)
509  return -1;
510  }
511 
512  if (unlikely (_pollset_size == 0)) {
513  if (timeout_ < 0) {
514  // Fail instead of trying to sleep forever
515  errno = EFAULT;
516  return -1;
517  }
518  // We'll report an error (timed out) as if the list was non-empty and
519  // no event occurred within the specified timeout. Otherwise the caller
520  // needs to check the return value AND the event to avoid using the
521  // nullified event data.
522  errno = EAGAIN;
523  if (timeout_ == 0)
524  return -1;
525 #if defined ZMQ_HAVE_WINDOWS
526  Sleep (timeout_ > 0 ? timeout_ : INFINITE);
527  return -1;
528 #elif defined ZMQ_HAVE_ANDROID
529  usleep (timeout_ * 1000);
530  return -1;
531 #elif defined ZMQ_HAVE_OSX
532  usleep (timeout_ * 1000);
533  errno = EAGAIN;
534  return -1;
535 #elif defined ZMQ_HAVE_VXWORKS
536  struct timespec ns_;
537  ns_.tv_sec = timeout_ / 1000;
538  ns_.tv_nsec = timeout_ % 1000 * 1000000;
539  nanosleep (&ns_, 0);
540  return -1;
541 #else
542  usleep (timeout_ * 1000);
543  return -1;
544 #endif
545  }
546 
547 #if defined ZMQ_POLL_BASED_ON_POLL
548  zmq::clock_t clock;
549  uint64_t now = 0;
550  uint64_t end = 0;
551 
552  bool first_pass = true;
553 
554  while (true) {
555  // Compute the timeout for the subsequent poll.
556  int timeout;
557  if (first_pass)
558  timeout = 0;
559  else if (timeout_ < 0)
560  timeout = -1;
561  else
562  timeout =
563  static_cast<int> (std::min<uint64_t> (end - now, INT_MAX));
564 
565  // Wait for events.
566  const int rc = poll (_pollfds, _pollset_size, timeout);
567  if (rc == -1 && errno == EINTR) {
568  return -1;
569  }
570  errno_assert (rc >= 0);
571 
572  // Receive the signal from pollfd
573  if (_use_signaler && _pollfds[0].revents & POLLIN)
574  _signaler->recv ();
575 
576  // Check for the events.
577  const int found = check_events (events_, n_events_);
578  if (found) {
579  if (found > 0)
580  zero_trail_events (events_, n_events_, found);
581  return found;
582  }
583 
584  // Adjust timeout or break
585  if (adjust_timeout (clock, timeout_, now, end, first_pass) == 0)
586  break;
587  }
588  errno = EAGAIN;
589  return -1;
590 
591 #elif defined ZMQ_POLL_BASED_ON_SELECT
592 
593  zmq::clock_t clock;
594  uint64_t now = 0;
595  uint64_t end = 0;
596 
597  bool first_pass = true;
598 
599  optimized_fd_set_t inset (_pollset_size);
600  optimized_fd_set_t outset (_pollset_size);
601  optimized_fd_set_t errset (_pollset_size);
602 
603  while (true) {
604  // Compute the timeout for the subsequent poll.
605  timeval timeout;
606  timeval *ptimeout;
607  if (first_pass) {
608  timeout.tv_sec = 0;
609  timeout.tv_usec = 0;
610  ptimeout = &timeout;
611  } else if (timeout_ < 0)
612  ptimeout = NULL;
613  else {
614  timeout.tv_sec = static_cast<long> ((end - now) / 1000);
615  timeout.tv_usec = static_cast<long> ((end - now) % 1000 * 1000);
616  ptimeout = &timeout;
617  }
618 
619  // Wait for events. Ignore interrupts if there's infinite timeout.
620  memcpy (inset.get (), _pollset_in.get (),
621  valid_pollset_bytes (*_pollset_in.get ()));
622  memcpy (outset.get (), _pollset_out.get (),
623  valid_pollset_bytes (*_pollset_out.get ()));
624  memcpy (errset.get (), _pollset_err.get (),
625  valid_pollset_bytes (*_pollset_err.get ()));
626  const int rc = select (static_cast<int> (_max_fd + 1), inset.get (),
627  outset.get (), errset.get (), ptimeout);
628 #if defined ZMQ_HAVE_WINDOWS
629  if (unlikely (rc == SOCKET_ERROR)) {
630  errno = wsa_error_to_errno (WSAGetLastError ());
631  wsa_assert (errno == ENOTSOCK);
632  return -1;
633  }
634 #else
635  if (unlikely (rc == -1)) {
636  errno_assert (errno == EINTR || errno == EBADF);
637  return -1;
638  }
639 #endif
640 
641  if (_use_signaler && FD_ISSET (_signaler->get_fd (), inset.get ()))
642  _signaler->recv ();
643 
644  // Check for the events.
645  const int found = check_events (events_, n_events_, *inset.get (),
646  *outset.get (), *errset.get ());
647  if (found) {
648  if (found > 0)
649  zero_trail_events (events_, n_events_, found);
650  return found;
651  }
652 
653  // Adjust timeout or break
654  if (adjust_timeout (clock, timeout_, now, end, first_pass) == 0)
655  break;
656  }
657 
658  errno = EAGAIN;
659  return -1;
660 
661 #else
662 
663  // Exotic platforms that support neither poll() nor select().
664  errno = ENOTSUP;
665  return -1;
666 
667 #endif
668 }
LIBZMQ_DELETE
#define LIBZMQ_DELETE(p_object)
Definition: macros.hpp:7
zmq::socket_poller_t::socket_poller_t
socket_poller_t()
Definition: socket_poller.cpp:29
zmq::poll
int poll(zmq_pollitem_t *items_, size_t nitems_, long timeout_=-1)
Definition: zmq.hpp:319
end
GLuint GLuint end
Definition: glcorearb.h:2858
ENOTSUP
#define ENOTSUP
Definition: zmq.h:104
NULL
NULL
Definition: test_security_zap.cpp:405
zmq::socket_base_t::remove_signaler
void remove_signaler(signaler_t *s_)
Definition: socket_base.cpp:504
EINTR
#define EINTR
Definition: errno.hpp:7
ZMQ_EVENTS
#define ZMQ_EVENTS
Definition: zmq.h:286
item
cJSON * item
Definition: cJSON.h:236
zmq::retired_fd
@ retired_fd
Definition: fd.hpp:32
EINVAL
#define EINVAL
Definition: errno.hpp:25
EAGAIN
#define EAGAIN
Definition: errno.hpp:14
precompiled.hpp
zmq_assert
#define zmq_assert(x)
Definition: err.hpp:102
ZMQ_POLLPRI
#define ZMQ_POLLPRI
Definition: zmq.h:485
zmq::socket_poller_t::signaler_fd
int signaler_fd(fd_t *fd_) const
Definition: socket_poller.cpp:74
zmq::socket_poller_t::add
int add(socket_base_t *socket_, void *user_data_, short events_)
Definition: socket_poller.cpp:85
polling_util.hpp
zmq::socket_poller_t::add_fd
int add_fd(fd_t fd_, void *user_data_, short events_)
Definition: socket_poller.cpp:135
if
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END if(!upb_strtable_init(&intern->table, UPB_CTYPE_UINT64))
Definition: php/ext/google/protobuf/map.c:232
errno
int errno
zmq::socket_base_t
Definition: socket_base.hpp:31
found
return found
Definition: socket_poller.cpp:456
T
#define T(upbtypeconst, upbtype, ctype, default_value)
zmq::fd_t
int fd_t
Definition: zmq.hpp:287
ZMQ_POLLIN
#define ZMQ_POLLIN
Definition: zmq.h:482
zmq::socket_base_t::add_signaler
void add_signaler(signaler_t *s_)
Definition: socket_base.cpp:496
zmq_poller_event_t::events
short events
Definition: zmq_draft.h:119
zmq::socket_poller_t::modify
int modify(const socket_base_t *socket_, short events_)
Definition: socket_poller.cpp:165
ZMQ_POLLOUT
#define ZMQ_POLLOUT
Definition: zmq.h:483
zmq_poller_event_t::socket
void * socket
Definition: zmq_draft.h:116
socket_poller.hpp
errno_assert
#define errno_assert(x)
Definition: err.hpp:113
zmq::socket_poller_t::~socket_poller_t
~socket_poller_t()
Definition: socket_poller.cpp:43
zmq::socket_poller_t::zero_trail_events
static void zero_trail_events(zmq::socket_poller_t::event_t *events_, int n_events_, int found_)
Definition: socket_poller.cpp:374
zmq::socket_poller_t::wait
int wait(event_t *events_, int n_events_, long timeout_)
Definition: socket_poller.cpp:497
macros.hpp
zmq::socket_poller_t::adjust_timeout
static int adjust_timeout(zmq::clock_t &clock_, long timeout_, uint64_t &now_, uint64_t &end_, bool &first_pass_)
Definition: socket_poller.cpp:460
zmq_poller_event_t
Definition: zmq_draft.h:114
EBADF
#define EBADF
Definition: errno.hpp:12
ZMQ_POLLERR
#define ZMQ_POLLERR
Definition: zmq.h:484
timeout
GLbitfield GLuint64 timeout
Definition: glcorearb.h:3588
ENOTSOCK
#define ENOTSOCK
Definition: zmq.h:128
FD_SETSIZE
#define FD_SETSIZE
Definition: deprecated-msvc/vs2015_xp/platform.hpp:10
zmq::socket_base_t::is_thread_safe
bool is_thread_safe() const
Definition: socket_base.cpp:122
zmq::socket_poller_t::modify_fd
int modify_fd(fd_t fd_, short events_)
Definition: socket_poller.cpp:182
i
int i
Definition: gmock-matchers_test.cc:764
zmq::signaler_t
Definition: signaler.hpp:20
zmq::socket_poller_t::check_tag
bool check_tag() const
Definition: socket_poller.cpp:69
zmq::clock_t
Definition: clock.hpp:27
err.hpp
zmq::socket_poller_t::remove_fd
int remove_fd(fd_t fd_)
Definition: socket_poller.cpp:219
zmq::clock_t::now_ms
uint64_t now_ms()
Definition: clock.cpp:181
b_
const char * b_
Definition: common_unittest.cc:194
check_events
static int check_events(const short events_)
Definition: zmq.cpp:1465
ZMQ_FD
#define ZMQ_FD
Definition: zmq.h:285
zmq::socket_poller_t::remove
int remove(socket_base_t *socket_)
Definition: socket_poller.cpp:199
zmq::socket_poller_t::rebuild
int rebuild()
Definition: socket_poller.cpp:235
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
zmq_poller_event_t::fd
zmq_fd_t fd
Definition: zmq_draft.h:117
EFAULT
#define EFAULT
Definition: errno.hpp:17
zmq::socket_poller_t::item_t
Definition: socket_poller.hpp:56
is_thread_safe
static bool is_thread_safe(const zmq::socket_base_t &socket_)
Definition: socket_poller.cpp:11
EMFILE
#define EMFILE
Definition: errno.hpp:27
zmq_poller_event_t::user_data
void * user_data
Definition: zmq_draft.h:118
it
MapIter it
Definition: php/ext/google/protobuf/map.c:205
unlikely
#define unlikely(x)
Definition: likely.hpp:11
find_if2
static It find_if2(It b_, It e_, const T &value, Pred pred)
Definition: socket_poller.cpp:19


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:58