diff options
author | Matt Messier <mmessier@grapetv.org> | 2007-05-18 12:39:25 -0400 |
---|---|---|
committer | Matt Messier <mmessier@grapetv.org> | 2007-05-18 12:39:25 -0400 |
commit | b9cedf245ca748915c739f9c9d14457cdf956a56 (patch) | |
tree | bb3c4258e71d7c26c7ba7713167b5091c0288586 /lib/timedlock.c | |
parent | 39fb90201a65dbaf15d285bd9e870dfd2fcc33ec (diff) | |
download | xine-lib-b9cedf245ca748915c739f9c9d14457cdf956a56.tar.gz xine-lib-b9cedf245ca748915c739f9c9d14457cdf956a56.tar.bz2 |
Work around missing pthread_mutex_timedlock() as necessary
Diffstat (limited to 'lib/timedlock.c')
-rw-r--r-- | lib/timedlock.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/timedlock.c b/lib/timedlock.c new file mode 100644 index 000000000..997ef6235 --- /dev/null +++ b/lib/timedlock.c @@ -0,0 +1,33 @@ +#include "config.h" + +#include <errno.h> + +#define _x_min(a, b) ((a) < (b) ? (a) : (b)) + +int xine_private_pthread_mutex_timedlock(pthread_mutex_t *mutex, + const struct timespec *abs_timeout) +{ + int pthread_rc; + struct timespec remaining, slept, ts; + + remaining = *abs_timeout; + while ((pthread_rc = pthread_mutex_trylock(mutex)) == EBUSY) { + ts.tv_sec = 0; + ts.tv_nsec = (remaining.tv_sec > 0 ? 10000000 + : _x_min(remaining.tv_nsec, 10000000)); + nanosleep(&ts, &slept); + ts.tv_nsec -= slept.tv_nsec; + if (ts.tv_nsec <= remaining.tv_nsec) { + remaining.tv_nsec -= ts.tv_nsec; + } + else { + remaining.tv_sec--; + remaining.tv_nsec = (1000000 - (ts.tv_nsec - remaining.tv_nsec)); + } + if (remaining.tv_sec < 0 || (!remaining.tv_sec && remaining.tv_nsec <= 0)) { + return ETIMEDOUT; + } + } + + return pthread_rc; +} |