From: Niklas Therning Date: Mon, 21 Nov 2016 09:17:40 +0000 (+0100) Subject: Fix assert in poll_event_wait() on WSAENOTSOCK on Windows X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=266345b394ef7f22b04bb7c9cd88c764616d90b9;p=mono.git Fix assert in poll_event_wait() on WSAENOTSOCK on Windows On Windows poll_event_wait() in threadpool-ms-io-poll.c checks WSAGetLastError() when mono_poll() fails. However, mono_poll() sets errno after converting the WSAXXX error code (e.g. WSAEFAULT->EFAULT). Occasionally (maybe 1 in 100) the System test suite fails due to mono_poll() returning an error and poll_event_wait() not handling the error code correctly on Windows. This patch changes poll_event_wait() to use the same code path which checks errno on all platforms including Windows. It also fixes a few other places which used to check WSAGetLastError() rather than errno after a call to mono_poll(). Also, the Socket.Poll_internal() and Socket.Select_internal() icalls had to be patched to convert back the errno value to a corresponding WSAXXX error code by adding WSABASEERR on Windows. --- diff --git a/mono/metadata/socket-io.c b/mono/metadata/socket-io.c index b5866b73a22..2e04a8e3dab 100644 --- a/mono/metadata/socket-io.c +++ b/mono/metadata/socket-io.c @@ -1242,7 +1242,7 @@ ves_icall_System_Net_Sockets_Socket_Poll_internal (SOCKET sock, gint mode, if (ret == -1) { #ifdef HOST_WIN32 - *werror = WSAGetLastError (); + *werror = errno > 0 && errno < WSABASEERR ? errno + WSABASEERR : errno; #else *werror = errno_to_WSA (errno, __func__); #endif @@ -1868,7 +1868,7 @@ ves_icall_System_Net_Sockets_Socket_Select_internal (MonoArray **sockets, gint32 if (ret == -1) { #ifdef HOST_WIN32 - *werror = WSAGetLastError (); + *werror = errno > 0 && errno < WSABASEERR ? errno + WSABASEERR : errno; #else *werror = errno_to_WSA (errno, __func__); #endif diff --git a/mono/metadata/threadpool-ms-io-poll.c b/mono/metadata/threadpool-ms-io-poll.c index 68e6611fba2..3d32130d3b5 100644 --- a/mono/metadata/threadpool-ms-io-poll.c +++ b/mono/metadata/threadpool-ms-io-poll.c @@ -117,11 +117,7 @@ poll_mark_bad_fds (mono_pollfd *poll_fds, gint poll_fds_size) ready++; break; case -1: -#if !defined(HOST_WIN32) if (errno == EBADF) -#else - if (WSAGetLastError () == WSAEBADF) -#endif { poll_fds [i].revents |= MONO_POLLNVAL; ready++; @@ -163,37 +159,21 @@ poll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gp * 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; } }