darwin: make uv_cond_timedwait() clock skew safe

Use pthread_cond_timedwait_relative_np() so we're not prone to spurious
bugs caused by clock skew.
This commit is contained in:
Ben Noordhuis 2013-02-06 23:24:49 +01:00
parent 5fa690397a
commit da33bba7c0
2 changed files with 7 additions and 16 deletions

View File

@ -1878,12 +1878,6 @@ UV_EXTERN void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex);
* 1. callers should be prepared to deal with spurious wakeups.
* 2. the granularity of timeout on Windows is never less than one millisecond.
* 3. uv_cond_timedwait takes a relative timeout, not an absolute time.
* 4. the precision of timeout on OSX is never less than one microsecond.
* Here is the reason.
* OSX doesn't support CLOCK_MONOTONIC nor pthread_condattr_setclock()
* (see man pthread_cond_init on OSX).
* An example in man pthread_cond_timedwait on OSX uses gettimeofday()
* and its resolution is a microsecond.
*/
UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex,
uint64_t timeout);

View File

@ -327,21 +327,18 @@ 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;
uint64_t abstime;
#if defined(__APPLE__) && defined(__MACH__)
{
struct timeval tv;
gettimeofday(&tv, NULL);
abstime = tv.tv_sec * 1e9 + tv.tv_usec * 1e3 + timeout;
}
ts.tv_sec = timeout / NANOSEC;
ts.tv_nsec = timeout % NANOSEC;
r = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
#else
abstime = uv__hrtime() + timeout;
timeout += uv__hrtime();
ts.tv_sec = timeout / NANOSEC;
ts.tv_nsec = timeout % NANOSEC;
r = pthread_cond_timedwait(cond, mutex, &ts);
#endif
ts.tv_sec = abstime / NANOSEC;
ts.tv_nsec = abstime % NANOSEC;
r = pthread_cond_timedwait(cond, mutex, &ts);
if (r == 0)
return 0;