From d8dd9a6725a0f9b961c641ed83b325bbdbb82482 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 31 Jan 2014 19:50:56 +0100 Subject: threads: add function to calculate deadline for timed waits Usually, you have to call pthread_cond_timedwait() in a loop (because it can wake up sporadically). If this function is used by another higher level function, which uses a relative timeout, we actually have to reduce the timeout on each iteration - or, simpler, compute the "deadline" at the beginning of the function, and always pass the same absolute time to the waiting function. Might be unsafe if the system time is changed. On the other hand, this is a fundamental race condition with these APIs. --- osdep/threads.c | 15 ++++++++++++--- osdep/threads.h | 2 ++ 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'osdep') diff --git a/osdep/threads.c b/osdep/threads.c index 0c31ffa40a..9a53d5c5c0 100644 --- a/osdep/threads.c +++ b/osdep/threads.c @@ -46,13 +46,22 @@ static void timespec_add_seconds(struct timespec *ts, double seconds) ts->tv_nsec += nsecs; } -// Call pthread_cond_timedwait() with a relative timeout in seconds -int mpthread_cond_timed_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, - double timeout) +// Return the argument to pass to e.g. pthread_cond_timedwait(). +// (Note that pthread_cond_t supports multiple clocks; this function computes +// the time value needed by the default clock.) +struct timespec mpthread_get_deadline(double timeout) { struct timespec ts; get_pthread_time(&ts); timespec_add_seconds(&ts, timeout); + return ts; +} + +// Call pthread_cond_timedwait() with a relative timeout in seconds +int mpthread_cond_timed_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, + double timeout) +{ + struct timespec ts = mpthread_get_deadline(timeout); return pthread_cond_timedwait(cond, mutex, &ts); } diff --git a/osdep/threads.h b/osdep/threads.h index 662f718f8c..3d060009cb 100644 --- a/osdep/threads.h +++ b/osdep/threads.h @@ -3,6 +3,8 @@ #include +struct timespec mpthread_get_deadline(double timeout); + int mpthread_cond_timed_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, double timeout); -- cgit v1.2.3