poll.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 
3 #include "precompiled.hpp"
4 #include "poll.hpp"
5 #if defined ZMQ_IOTHREAD_POLLER_USE_POLL
6 
7 #include <sys/types.h>
8 #include <sys/time.h>
9 #include <poll.h>
10 #include <algorithm>
11 
12 #include "poll.hpp"
13 #include "err.hpp"
14 #include "config.hpp"
15 #include "i_poll_events.hpp"
16 
17 zmq::poll_t::poll_t (const zmq::thread_ctx_t &ctx_) :
18  worker_poller_base_t (ctx_), retired (false)
19 {
20 }
21 
22 zmq::poll_t::~poll_t ()
23 {
24  stop_worker ();
25 }
26 
27 zmq::poll_t::handle_t zmq::poll_t::add_fd (fd_t fd_, i_poll_events *events_)
28 {
29  check_thread ();
30  zmq_assert (fd_ != retired_fd);
31 
32  // If the file descriptor table is too small expand it.
33  fd_table_t::size_type sz = fd_table.size ();
34  if (sz <= (fd_table_t::size_type) fd_) {
35  fd_table.resize (fd_ + 1);
36  while (sz != (fd_table_t::size_type) (fd_ + 1)) {
37  fd_table[sz].index = retired_fd;
38  ++sz;
39  }
40  }
41 
42  pollfd pfd = {fd_, 0, 0};
43  pollset.push_back (pfd);
44  zmq_assert (fd_table[fd_].index == retired_fd);
45 
46  fd_table[fd_].index = pollset.size () - 1;
47  fd_table[fd_].events = events_;
48 
49  // Increase the load metric of the thread.
50  adjust_load (1);
51 
52  return fd_;
53 }
54 
55 void zmq::poll_t::rm_fd (handle_t handle_)
56 {
57  check_thread ();
58  fd_t index = fd_table[handle_].index;
60 
61  // Mark the fd as unused.
62  pollset[index].fd = retired_fd;
63  fd_table[handle_].index = retired_fd;
64  retired = true;
65 
66  // Decrease the load metric of the thread.
67  adjust_load (-1);
68 }
69 
70 void zmq::poll_t::set_pollin (handle_t handle_)
71 {
72  check_thread ();
73  fd_t index = fd_table[handle_].index;
74  pollset[index].events |= POLLIN;
75 }
76 
77 void zmq::poll_t::reset_pollin (handle_t handle_)
78 {
79  check_thread ();
80  fd_t index = fd_table[handle_].index;
81  pollset[index].events &= ~((short) POLLIN);
82 }
83 
84 void zmq::poll_t::set_pollout (handle_t handle_)
85 {
86  check_thread ();
87  fd_t index = fd_table[handle_].index;
88  pollset[index].events |= POLLOUT;
89 }
90 
91 void zmq::poll_t::reset_pollout (handle_t handle_)
92 {
93  check_thread ();
94  fd_t index = fd_table[handle_].index;
95  pollset[index].events &= ~((short) POLLOUT);
96 }
97 
98 void zmq::poll_t::stop ()
99 {
100  check_thread ();
101  // no-op... thread is stopped when no more fds or timers are registered
102 }
103 
104 int zmq::poll_t::max_fds ()
105 {
106  return -1;
107 }
108 
109 void zmq::poll_t::loop ()
110 {
111  while (true) {
112  // Execute any due timers.
113  int timeout = (int) execute_timers ();
114 
115  cleanup_retired ();
116 
117  if (pollset.empty ()) {
118  zmq_assert (get_load () == 0);
119 
120  if (timeout == 0)
121  break;
122 
123  // TODO sleep for timeout
124  continue;
125  }
126 
127  // Wait for events.
128  int rc = poll (&pollset[0], static_cast<nfds_t> (pollset.size ()),
129  timeout ? timeout : -1);
130  if (rc == -1) {
131  errno_assert (errno == EINTR);
132  continue;
133  }
134 
135  // If there are no events (i.e. it's a timeout) there's no point
136  // in checking the pollset.
137  if (rc == 0)
138  continue;
139 
140  for (pollset_t::size_type i = 0; i != pollset.size (); i++) {
141  zmq_assert (!(pollset[i].revents & POLLNVAL));
142  if (pollset[i].fd == retired_fd)
143  continue;
144  if (pollset[i].revents & (POLLERR | POLLHUP))
145  fd_table[pollset[i].fd].events->in_event ();
146  if (pollset[i].fd == retired_fd)
147  continue;
148  if (pollset[i].revents & POLLOUT)
149  fd_table[pollset[i].fd].events->out_event ();
150  if (pollset[i].fd == retired_fd)
151  continue;
152  if (pollset[i].revents & POLLIN)
153  fd_table[pollset[i].fd].events->in_event ();
154  }
155  }
156 }
157 
158 void zmq::poll_t::cleanup_retired ()
159 {
160  // Clean up the pollset and update the fd_table accordingly.
161  if (retired) {
162  pollset_t::size_type i = 0;
163  while (i < pollset.size ()) {
164  if (pollset[i].fd == retired_fd)
165  pollset.erase (pollset.begin () + i);
166  else {
167  fd_table[pollset[i].fd].index = i;
168  i++;
169  }
170  }
171  retired = false;
172  }
173 }
174 
175 
176 #endif
i_poll_events.hpp
EINTR
#define EINTR
Definition: errno.hpp:7
config.hpp
precompiled.hpp
zmq_assert
#define zmq_assert(x)
Definition: err.hpp:102
errno
int errno
retired_fd
@ retired_fd
Definition: libzmq/tests/testutil.hpp:117
errno_assert
#define errno_assert(x)
Definition: err.hpp:113
zmq::detail::poll
int poll(zmq_pollitem_t *items_, size_t nitems_, long timeout_)
Definition: zmq.hpp:306
timeout
GLbitfield GLuint64 timeout
Definition: glcorearb.h:3588
i
int i
Definition: gmock-matchers_test.cc:764
zmq::thread_ctx_t
Definition: ctx.hpp:37
poll.hpp
err.hpp
fd_t
zmq_fd_t fd_t
Definition: libzmq/tests/testutil.hpp:98
false
#define false
Definition: cJSON.c:70
index
GLuint index
Definition: glcorearb.h:3055


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