summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-01-31 19:50:56 +0100
committerwm4 <wm4@nowhere>2014-01-31 22:17:43 +0100
commitd8dd9a6725a0f9b961c641ed83b325bbdbb82482 (patch)
treeb49838266b80da294ecb4e89028b4d2bc36315e1
parenta17be5576fae918c683688a0e2bd2fd21b32d428 (diff)
downloadmpv-d8dd9a6725a0f9b961c641ed83b325bbdbb82482.tar.bz2
mpv-d8dd9a6725a0f9b961c641ed83b325bbdbb82482.tar.xz
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.
-rw-r--r--osdep/threads.c15
-rw-r--r--osdep/threads.h2
2 files changed, 14 insertions, 3 deletions
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 <pthread.h>
+struct timespec mpthread_get_deadline(double timeout);
+
int mpthread_cond_timed_wait(pthread_cond_t *cond, pthread_mutex_t *mutex,
double timeout);