summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac7
-rw-r--r--lib/os_internal.h9
-rw-r--r--lib/timedlock.c33
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;
+}