static gint
epoll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
{
	gint i, ready;

	memset (epoll_events, 0, sizeof (struct epoll_event) * EPOLL_NEVENTS);

	mono_gc_set_skip_thread (TRUE);

	MONO_ENTER_GC_SAFE;
	ready = epoll_wait (epoll_fd, epoll_events, EPOLL_NEVENTS, -1);
	MONO_EXIT_GC_SAFE;

	mono_gc_set_skip_thread (FALSE);

	if (ready == -1) {
		switch (errno) {
		case EINTR:
			mono_thread_internal_check_for_interruption_critical (mono_thread_internal_current ());
			ready = 0;
			break;
		default:
			g_error ("epoll_event_wait: epoll_wait () failed, error (%d) %s", errno, g_strerror (errno));
			break;
		}
	}

	if (ready == -1)
		return -1;

	for (i = 0; i < ready; ++i) {
		gint fd, events = 0;

		fd = epoll_events [i].data.fd;
		if (epoll_events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP))
			events |= EVENT_IN;
		if (epoll_events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
			events |= EVENT_OUT;

		callback (fd, events, user_data);
	}

	return 0;
}
static gint
kqueue_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
{
	gint i, ready;

	memset (kqueue_events, 0, sizeof (struct kevent) * KQUEUE_NEVENTS);

	mono_gc_set_skip_thread (TRUE);

	ready = kevent (kqueue_fd, NULL, 0, kqueue_events, KQUEUE_NEVENTS, NULL);

	mono_gc_set_skip_thread (FALSE);

	if (ready == -1) {
		switch (errno) {
		case EINTR:
			mono_thread_internal_check_for_interruption_critical (mono_thread_internal_current ());
			ready = 0;
			break;
		default:
			g_error ("kqueue_event_wait: kevent () failed, error (%d) %s", errno, g_strerror (errno));
			break;
		}
	}

	if (ready == -1)
		return -1;

	for (i = 0; i < ready; ++i) {
		gint fd, events = 0;

		fd = kqueue_events [i].ident;
		if (kqueue_events [i].filter == EVFILT_READ || (kqueue_events [i].flags & EV_ERROR) != 0)
			events |= EVENT_IN;
		if (kqueue_events [i].filter == EVFILT_WRITE || (kqueue_events [i].flags & EV_ERROR) != 0)
			events |= EVENT_OUT;

		callback (fd, events, user_data);
	}

	return 0;
}
Beispiel #3
0
static gint
kqueue_event_wait (void)
{
	gint ready;

	ready = kevent (kqueue_fd, NULL, 0, kqueue_events, KQUEUE_NEVENTS, NULL);
	if (ready == -1) {
		switch (errno) {
		case EINTR:
			mono_thread_internal_check_for_interruption_critical (mono_thread_internal_current ());
			ready = 0;
			break;
		default:
			g_warning ("kqueue_event_wait: kevent () failed, error (%d) %s", errno, g_strerror (errno));
			break;
		}
	}

	return ready;
}
Beispiel #4
0
static gint
epoll_event_wait (void)
{
	gint ready;

	ready = epoll_wait (epoll_fd, epoll_events, EPOLL_NEVENTS, -1);
	if (ready == -1) {
		switch (errno) {
		case EINTR:
			mono_thread_internal_check_for_interruption_critical (mono_thread_internal_current ());
			ready = 0;
			break;
		default:
			g_warning ("epoll_event_wait: epoll_wait () failed, error (%d) %s", errno, g_strerror (errno));
			break;
		}
	}

	return ready;
}
Beispiel #5
0
static gint
poll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
{
	gint i, ready;

	for (i = 0; i < poll_fds_size; ++i)
		poll_fds [i].revents = 0;

	mono_gc_set_skip_thread (TRUE);

	MONO_ENTER_GC_SAFE;
	ready = mono_poll (poll_fds, poll_fds_size, -1);
	MONO_EXIT_GC_SAFE;

	mono_gc_set_skip_thread (FALSE);

	if (ready == -1) {
		/*
		 * Apart from EINTR, we only check EBADF, for the rest:
		 *  EINVAL: mono_poll() 'protects' us from descriptor
		 *      numbers above the limit if using select() by marking
		 *      then as POLLERR.  If a system poll() is being
		 *      used, the number of descriptor we're passing will not
		 *      be over sysconf(_SC_OPEN_MAX), as the error would have
		 *      happened when opening.
		 *
		 *  EFAULT: we own the memory pointed by pfds.
		 *  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;
		}
#if !defined(HOST_WIN32)
		case EBADF:
#else
		case WSAEBADF:
#endif
		{
			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;

		if (poll_fds [i].fd == -1)
			continue;
		if (poll_fds [i].revents == 0)
			continue;

		fd = poll_fds [i].fd;
		if (poll_fds [i].revents & (MONO_POLLIN | MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL))
			events |= EVENT_IN;
		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);

		if (--ready == 0)
			break;
	}

	return 0;
}