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.
if (ret == -1) {
#ifdef HOST_WIN32
if (ret == -1) {
#ifdef HOST_WIN32
- *werror = WSAGetLastError ();
+ *werror = errno > 0 && errno < WSABASEERR ? errno + WSABASEERR : errno;
#else
*werror = errno_to_WSA (errno, __func__);
#endif
#else
*werror = errno_to_WSA (errno, __func__);
#endif
if (ret == -1) {
#ifdef HOST_WIN32
if (ret == -1) {
#ifdef HOST_WIN32
- *werror = WSAGetLastError ();
+ *werror = errno > 0 && errno < WSABASEERR ? errno + WSABASEERR : errno;
#else
*werror = errno_to_WSA (errno, __func__);
#endif
#else
*werror = errno_to_WSA (errno, __func__);
#endif
-#if !defined(HOST_WIN32)
-#else
- if (WSAGetLastError () == WSAEBADF)
-#endif
{
poll_fds [i].revents |= MONO_POLLNVAL;
ready++;
{
poll_fds [i].revents |= MONO_POLLNVAL;
ready++;
* ENOMEM: we're doomed anyway
*
*/
* ENOMEM: we're doomed anyway
*
*/
-#if !defined(HOST_WIN32)
-#else
- switch (WSAGetLastError ())
-#endif
-#if !defined(HOST_WIN32)
-#else
- case WSAEINTR:
-#endif
{
mono_thread_internal_check_for_interruption_critical (mono_thread_internal_current ());
ready = 0;
break;
}
{
mono_thread_internal_check_for_interruption_critical (mono_thread_internal_current ());
ready = 0;
break;
}
-#if !defined(HOST_WIN32)
-#else
- case WSAEBADF:
-#endif
{
ready = poll_mark_bad_fds (poll_fds, poll_fds_size);
break;
}
default:
{
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));
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