zos: fix timeout for condition variable

The pthread_cond_timedwait requires a timeout relative to the Epoch.
So don't use uv__hrtime to set the timeout because it is relative to an
arbitrary time in the past. Use gettimeofday instead.

PR-URL: https://github.com/libuv/libuv/pull/1711
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Jamie Davis <davisjam@vt.edu>
This commit is contained in:
John Barboza 2018-01-17 10:30:48 -05:00 committed by Ben Noordhuis
parent 95e44dd46e
commit 1ded66908d
2 changed files with 18 additions and 2 deletions

View File

@ -131,8 +131,15 @@ Functions return 0 on success or an error code < 0 (unless the
return type is void, of course).
.. note::
Callers should be prepared to deal with spurious wakeups on :c:func:`uv_cond_wait` and
:c:func:`uv_cond_timedwait`.
1. Callers should be prepared to deal with spurious wakeups on :c:func:`uv_cond_wait`
and :c:func:`uv_cond_timedwait`.
2. The timeout parameter for :c:func:`uv_cond_timedwait` is relative to the time
at which function is called.
3. On z/OS, the timeout parameter for :c:func:`uv_cond_timedwait` is converted to an
absolute system time at which the wait expires. If the current system clock time
passes the absolute time calculated before the condition is signaled, an ETIMEDOUT
error results. After the wait begins, the wait time is not affected by changes
to the system clock.
.. c:function:: int uv_cond_init(uv_cond_t* cond)
.. c:function:: void uv_cond_destroy(uv_cond_t* cond)

View File

@ -646,13 +646,22 @@ void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
int r;
struct timespec ts;
#if defined(__MVS__)
struct timeval tv;
#endif
#if defined(__APPLE__) && defined(__MACH__)
ts.tv_sec = timeout / NANOSEC;
ts.tv_nsec = timeout % NANOSEC;
r = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
#else
#if defined(__MVS__)
if (gettimeofday(&tv, NULL))
abort();
timeout += tv.tv_sec * NANOSEC + tv.tv_usec * 1e3;
#else
timeout += uv__hrtime(UV_CLOCK_PRECISE);
#endif
ts.tv_sec = timeout / NANOSEC;
ts.tv_nsec = timeout % NANOSEC;
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21