2 #include "utils/mono-poll.h"
4 static mono_pollfd *poll_fds;
5 static guint poll_fds_capacity;
6 static guint poll_fds_size;
9 POLL_INIT_FD (mono_pollfd *poll_fd, gint fd, gint events)
12 poll_fd->events = events;
17 poll_init (gint wakeup_pipe_fd)
19 g_assert (wakeup_pipe_fd >= 0);
22 poll_fds_capacity = 64;
24 poll_fds = g_new0 (mono_pollfd, poll_fds_capacity);
26 POLL_INIT_FD (&poll_fds [0], wakeup_pipe_fd, MONO_POLLIN);
38 poll_register_fd (gint fd, gint events, gboolean is_new)
44 g_assert (poll_fds_size <= poll_fds_capacity);
46 g_assert ((events & ~(EVENT_IN | EVENT_OUT)) == 0);
49 if (events & EVENT_IN)
50 poll_event |= MONO_POLLIN;
51 if (events & EVENT_OUT)
52 poll_event |= MONO_POLLOUT;
54 for (i = 0; i < poll_fds_size; ++i) {
55 if (poll_fds [i].fd == fd) {
57 POLL_INIT_FD (&poll_fds [i], fd, poll_event);
64 for (i = 0; i < poll_fds_size; ++i) {
65 if (poll_fds [i].fd == -1) {
66 POLL_INIT_FD (&poll_fds [i], fd, poll_event);
73 if (poll_fds_size > poll_fds_capacity) {
74 poll_fds_capacity *= 2;
75 g_assert (poll_fds_size <= poll_fds_capacity);
77 poll_fds = g_renew (mono_pollfd, poll_fds, poll_fds_capacity);
80 POLL_INIT_FD (&poll_fds [poll_fds_size - 1], fd, poll_event);
84 poll_remove_fd (gint fd)
90 for (i = 0; i < poll_fds_size; ++i) {
91 if (poll_fds [i].fd == fd) {
92 POLL_INIT_FD (&poll_fds [i], -1, 0);
97 /* if we don't find the fd in poll_fds,
98 * it means we try to delete it twice */
99 g_assert (i < poll_fds_size);
101 /* if we find it again, it means we added
103 for (; i < poll_fds_size; ++i)
104 g_assert (poll_fds [i].fd != fd);
106 /* reduce the value of poll_fds_size so we
107 * do not keep it too big */
108 while (poll_fds_size > 1 && poll_fds [poll_fds_size - 1].fd == -1)
113 poll_mark_bad_fds (mono_pollfd *poll_fds, gint poll_fds_size)
117 for (i = 0; i < poll_fds_size; i++) {
118 if (poll_fds [i].fd == -1)
121 switch (mono_poll (&poll_fds [i], 1, 0)) {
126 #if !defined(HOST_WIN32)
129 if (WSAGetLastError () == WSAEBADF)
132 poll_fds [i].revents |= MONO_POLLNVAL;
143 poll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
147 for (i = 0; i < poll_fds_size; ++i)
148 poll_fds [i].revents = 0;
150 mono_gc_set_skip_thread (TRUE);
152 ready = mono_poll (poll_fds, poll_fds_size, -1);
154 mono_gc_set_skip_thread (FALSE);
158 * Apart from EINTR, we only check EBADF, for the rest:
159 * EINVAL: mono_poll() 'protects' us from descriptor
160 * numbers above the limit if using select() by marking
161 * then as POLLERR. If a system poll() is being
162 * used, the number of descriptor we're passing will not
163 * be over sysconf(_SC_OPEN_MAX), as the error would have
164 * happened when opening.
166 * EFAULT: we own the memory pointed by pfds.
167 * ENOMEM: we're doomed anyway
170 #if !defined(HOST_WIN32)
173 switch (WSAGetLastError ())
176 #if !defined(HOST_WIN32)
182 mono_thread_internal_check_for_interruption_critical (mono_thread_internal_current ());
186 #if !defined(HOST_WIN32)
192 ready = poll_mark_bad_fds (poll_fds, poll_fds_size);
196 #if !defined(HOST_WIN32)
197 g_error ("poll_event_wait: mono_poll () failed, error (%d) %s", errno, g_strerror (errno));
199 g_error ("poll_event_wait: mono_poll () failed, error (%d)\n", WSAGetLastError ());
210 g_assert (ready > 0);
212 for (i = 0; i < poll_fds_size; ++i) {
215 if (poll_fds [i].fd == -1)
217 if (poll_fds [i].revents == 0)
220 fd = poll_fds [i].fd;
221 if (poll_fds [i].revents & (MONO_POLLIN | MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL))
223 if (poll_fds [i].revents & (MONO_POLLOUT | MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL))
225 if (poll_fds [i].revents & (MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL))
228 callback (fd, events, user_data);
237 static ThreadPoolIOBackend backend_poll = {
239 .cleanup = poll_cleanup,
240 .register_fd = poll_register_fd,
241 .remove_fd = poll_remove_fd,
242 .event_wait = poll_event_wait,