return 0;
}
+static int
+futex_istimeout(struct timeval *timeout)
+{
+ int ret;
+ struct timeval tv;
+
+ if (timeout == NULL)
+ return 0;
+
+ ret = gettimeofday(&tv, NULL);
+ if (ret != 0)
+ return ret;
+
+ return (tv.tv_sec > timeout->tv_sec) ||
+ ((tv.tv_sec == timeout->tv_sec) && tv.tv_usec > timeout->tv_usec);
+}
+
int
futex_wait(int *lock_word, int oldval, long sec, unsigned long usec)
{
int ret, result;
struct futex *futex;
sigset_t oldset, newset;
+ struct timeval tv, *timeout;
sigemptyset(&newset);
sigaddset_deferrable(&newset);
again:
+ if (sec < 0)
+ timeout = NULL;
+ else {
+ ret = gettimeofday(&tv, NULL);
+ if (ret != 0)
+ return ret;
+ tv.tv_sec = tv.tv_sec + sec + (tv.tv_usec + usec) / 1000000;
+ tv.tv_usec = (tv.tv_usec + usec) % 1000000;
+ timeout = &tv;
+ }
+
pthread_sigmask(SIG_BLOCK, &newset, &oldset);
futex = futex_get(lock_word);
&abstime);
futex_assert(result == 0 || result == ETIMEDOUT);
- if (result != ETIMEDOUT)
+ if (result != ETIMEDOUT || futex_istimeout(timeout))
break;
/* futex system call of Linux returns with EINTR errno when
goto again;
}
+ if (result == ETIMEDOUT)
+ return 1;
+
return result;
}
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.5.15"
+"1.0.5.16"