-#if defined(HAVE_POLL)
-
-#if defined(HAVE_POLL_H)
-#include <poll.h>
-#elif defined(HAVE_SYS_POLL_H)
-#include <sys/poll.h>
-#endif
-
-typedef struct pollfd mono_pollfd;
-
-#elif defined(HOST_WIN32)
-
-#include "mswsock.h"
-
-typedef WSAPOLLFD mono_pollfd;
-
-#else
-/* poll is not defined */
-#error
-#endif
+#include "utils/mono-poll.h"
static mono_pollfd *poll_fds;
static guint poll_fds_capacity;
poll_fds = g_new0 (mono_pollfd, poll_fds_capacity);
- POLL_INIT_FD (&poll_fds [0], wakeup_pipe_fd, POLLIN);
+ POLL_INIT_FD (&poll_fds [0], wakeup_pipe_fd, MONO_POLLIN);
return TRUE;
}
-static void
-poll_cleanup (void)
-{
- g_free (poll_fds);
-}
-
static void
poll_register_fd (gint fd, gint events, gboolean is_new)
{
poll_event = 0;
if (events & EVENT_IN)
- poll_event |= POLLIN;
+ poll_event |= MONO_POLLIN;
if (events & EVENT_OUT)
- poll_event |= POLLOUT;
+ poll_event |= MONO_POLLOUT;
for (i = 0; i < poll_fds_size; ++i) {
if (poll_fds [i].fd == fd) {
poll_fds_capacity *= 2;
g_assert (poll_fds_size <= poll_fds_capacity);
- poll_fds = g_renew (mono_pollfd, poll_fds, poll_fds_capacity);
+ poll_fds = (mono_pollfd *)g_renew (mono_pollfd, poll_fds, poll_fds_capacity);
}
POLL_INIT_FD (&poll_fds [poll_fds_size - 1], fd, poll_event);
poll_fds_size -= 1;
}
+static inline gint
+poll_mark_bad_fds (mono_pollfd *poll_fds, gint poll_fds_size)
+{
+ gint i, ready = 0;
+
+ for (i = 0; i < poll_fds_size; i++) {
+ if (poll_fds [i].fd == -1)
+ continue;
+
+ switch (mono_poll (&poll_fds [i], 1, 0)) {
+ case 1:
+ ready++;
+ break;
+ case -1:
+ if (errno == EBADF)
+ {
+ poll_fds [i].revents |= MONO_POLLNVAL;
+ ready++;
+ }
+ break;
+ }
+ }
+
+ return ready;
+}
+
static gint
poll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
{
mono_gc_set_skip_thread (TRUE);
-#if !defined(HOST_WIN32)
- ready = poll (poll_fds, poll_fds_size, -1);
-#else
- ready = WSAPoll(poll_fds, poll_fds_size, -1);
- if (ready == SOCKET_ERROR)
- ready = -1;
-#endif
+ MONO_ENTER_GC_SAFE;
+ ready = mono_poll (poll_fds, poll_fds_size, -1);
+ MONO_EXIT_GC_SAFE;
mono_gc_set_skip_thread (FALSE);
* ENOMEM: we're doomed anyway
*
*/
-#if !defined(HOST_WIN32)
switch (errno)
-#else
- switch (WSAGetLastError ())
-#endif
{
-#if !defined(HOST_WIN32)
case EINTR:
-#else
- case WSAEINTR:
-#endif
{
mono_thread_internal_check_for_interruption_critical (mono_thread_internal_current ());
ready = 0;
break;
}
+ case EBADF:
+ {
+ ready = poll_mark_bad_fds (poll_fds, poll_fds_size);
+ break;
+ }
default:
-#if !defined(HOST_WIN32)
g_error ("poll_event_wait: mono_poll () failed, error (%d) %s", errno, g_strerror (errno));
-#else
- g_error ("poll_event_wait: mono_poll () failed, error (%d)\n", WSAGetLastError ());
-#endif
break;
}
}
if (ready == -1)
return -1;
+ if (ready == 0)
+ return 0;
+
+ g_assert (ready > 0);
for (i = 0; i < poll_fds_size; ++i) {
gint fd, events = 0;
continue;
fd = poll_fds [i].fd;
- if (poll_fds [i].revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL))
+ if (poll_fds [i].revents & (MONO_POLLIN | MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL))
events |= EVENT_IN;
- if (poll_fds [i].revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL))
+ if (poll_fds [i].revents & (MONO_POLLOUT | MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL))
events |= EVENT_OUT;
+ if (poll_fds [i].revents & (MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL))
+ events |= EVENT_ERR;
callback (fd, events, user_data);
static ThreadPoolIOBackend backend_poll = {
.init = poll_init,
- .cleanup = poll_cleanup,
.register_fd = poll_register_fd,
.remove_fd = poll_remove_fd,
.event_wait = poll_event_wait,