+ return sem_trywait (sem);
+#endif
+ if (timeout_ms == (guint32) 0xFFFFFFFF)
+ return mono_sem_wait (sem, alertable);
+
+#ifdef USE_MACH_SEMA
+ memset (&t, 0, sizeof (TIMESPEC));
+#else
+ gettimeofday (&t, NULL);
+#endif
+ ts.tv_sec = timeout_ms / 1000 + t.tv_sec;
+ ts.tv_nsec = (timeout_ms % 1000) * 1000000 + t.tv_usec * 1000;
+ while (ts.tv_nsec > NSEC_PER_SEC) {
+ ts.tv_nsec -= NSEC_PER_SEC;
+ ts.tv_sec++;
+ }
+#if defined(__OpenBSD__)
+ timeout = ts.tv_sec;
+ while (timeout) {
+ if ((res = WAIT_BLOCK (sem)) == 0)
+ return res;
+
+ if (alertable)
+ return -1;
+
+ usleep (ts.tv_nsec / 1000);
+ timeout--;
+ }
+#else
+ copy = ts;
+ while ((res = WAIT_BLOCK (sem, &ts)) == -1 && errno == EINTR) {
+ struct timeval current;
+ if (alertable)
+ return -1;
+#ifdef USE_MACH_SEMA
+ memset (¤t, 0, sizeof (TIMESPEC));
+#else
+ gettimeofday (¤t, 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) {
+ if (ts.tv_sec <= 0) {
+ ts.tv_nsec = 0;
+ } else {
+ ts.tv_sec--;
+ ts.tv_nsec += NSEC_PER_SEC;
+ }
+ }
+ if (ts.tv_sec < 0) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+ }
+#endif
+ /* OSX might return > 0 for error */
+ if (res != 0)
+ res = -1;
+ return res;
+}
+
+int
+mono_sem_wait (MonoSemType *sem, gboolean alertable)
+{
+ int res;
+#ifndef USE_MACH_SEMA
+ while ((res = sem_wait (sem) == -1) && errno == EINTR)
+#else
+ while ((res = semaphore_wait (*sem) == -1) && errno == EINTR)