Example #1
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;
}
Example #2
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_thread_info_set_flags (MONO_THREAD_INFO_FLAGS_NO_GC);

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

	mono_thread_info_set_flags (MONO_THREAD_INFO_FLAGS_NONE);

	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
		 *
		 */
		switch (errno)
		{
		case EINTR:
		{
			ready = 0;
			break;
		}
		case EBADF:
		{
			ready = poll_mark_bad_fds (poll_fds, poll_fds_size);
			break;
		}
		default:
			g_error ("poll_event_wait: mono_poll () failed, error (%d) %s", errno, g_strerror (errno));
			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;
}