[runtime] Fix mono_sem_timedwait for the case where we get interrupted.
authorVlad Brezae <brezaevlad@gmail.com>
Mon, 15 Jun 2015 21:25:20 +0000 (14:25 -0700)
committerVlad Brezae <brezaevlad@gmail.com>
Mon, 15 Jun 2015 22:10:23 +0000 (15:10 -0700)
On mach, semaphore_timedwait returns KERN_ABORTED instead of setting the errno variable. The timeout argument is relative so it needs to be updated. We don't need to update the timeout argument on other platforms since it has an absolute value.

mono/utils/mono-semaphore.c

index 124700a9efb70fe77738bf4c2a6ae901b781042d..6c857fe823951c21df058ba1773856689ac2d0cf 100644 (file)
@@ -61,16 +61,21 @@ mono_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, gboolean alertable)
        }
 
        copy = ts;
-       while ((res = WAIT_BLOCK (sem, &ts)) == -1 && errno == EINTR) {
+#ifdef USE_MACH_SEMA
+       gettimeofday (&t, NULL);
+       while ((res = WAIT_BLOCK (sem, &ts)) == KERN_ABORTED)
+#else
+       while ((res = WAIT_BLOCK (sem, &ts)) == -1 && errno == EINTR)
+#endif
+       {
+#ifdef USE_MACH_SEMA
                struct timeval current;
+#endif
                if (alertable)
                        return -1;
+               ts = copy;
 #ifdef USE_MACH_SEMA
-               memset (&current, 0, sizeof (current));
-#else
                gettimeofday (&current, NULL);
-#endif
-               ts = copy;
                ts.tv_sec -= (current.tv_sec - t.tv_sec);
                ts.tv_nsec -= (current.tv_usec - t.tv_usec) * 1000;
                if (ts.tv_nsec < 0) {
@@ -85,6 +90,7 @@ mono_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, gboolean alertable)
                        ts.tv_sec = 0;
                        ts.tv_nsec = 0;
                }
+#endif
        }
 
        /* OSX might return > 0 for error */