diff options
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | lib/os_internal.h | 9 | ||||
-rw-r--r-- | lib/timedlock.c | 33 |
3 files changed, 48 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index a810796de..10fd9116b 100644 --- a/configure.ac +++ b/configure.ac @@ -889,6 +889,13 @@ AC_CHECK_FUNC([opendir], AC_MSG_ERROR([dirent is needed (opendir, readdir, ...)]) fi]) +AC_LIBSOURCE([timedlock.c]) +ac_save_LIBS="$LIBS" LIBS="$LIBS $PTHREAD_LIBS" +AC_CHECK_FUNCS([pthread_mutex_timedlock], + [AC_DEFINE([HAVE_PTHREAD_MUTEX_TIMEDLOCK], 1, [Define to 1 if you have 'pthread_mutex_timedlock' in <pthread.h>])], + [AC_LIBOBJ([timedlock])]) +LIBS="$ac_save_LIBS" + dnl -------------------------- dnl checks for system services diff --git a/lib/os_internal.h b/lib/os_internal.h index 49b9330e5..b618b3952 100644 --- a/lib/os_internal.h +++ b/lib/os_internal.h @@ -79,7 +79,7 @@ #endif #include <inttypes.h> - +#include <pthread.h> #if defined(WIN32) || defined(__CYGWIN__) # define XINE_PATH_SEPARATOR_STRING ";" @@ -193,6 +193,13 @@ int xine_private_vasprintf(char **string, const char *format, va_list ap) XINE_F char *xine_private_strndup(const char *s, size_t n); #endif +/* replacement of pthread_mutex_timedlock */ +#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK +#define HAVE_PTHREAD_MUTEX_TIMEDLOCK +#define pthread_mutex_timedlock(M, T) xine_private_pthread_mutex_timedlock((M), (T)) +int xine_private_pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abs_timeout); +#endif + /* handle non-standard function names */ #if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF) # define HAVE_SNPRINTF 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; +} |