mirror of https://git.tukaani.org/xz.git
Fix portability problems in mythread.h.
Use gettimeofday() if clock_gettime() isn't available (e.g. Darwin). The test for availability of pthread_condattr_setclock() and CLOCK_MONOTONIC was incorrect. Instead of fixing the #ifdefs, use an Autoconf test. That way if there exists a system that supports them but doesn't specify the matching POSIX #defines, the features will still get detected. Don't try to use pthread_sigmask() on OpenVMS. It doesn't have that function. Guard mythread.h against being #included multiple times.
This commit is contained in:
parent
3de00cc75d
commit
9c1b05828a
|
@ -435,7 +435,14 @@ if test "x$enable_threads" = xyes; then
|
||||||
LIBS="$LIBS $PTHREAD_LIBS"
|
LIBS="$LIBS $PTHREAD_LIBS"
|
||||||
AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS"
|
AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS"
|
||||||
CC="$PTHREAD_CC"
|
CC="$PTHREAD_CC"
|
||||||
|
|
||||||
|
# These are nice to have but not mandatory.
|
||||||
|
OLD_CFLAGS=$CFLAGS
|
||||||
|
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||||
|
AC_CHECK_FUNCS([clock_gettime pthread_condattr_setclock])
|
||||||
|
AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
|
||||||
|
CFLAGS=$OLD_CFLAGS
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([COND_THREADS], [test "x$ax_pthread_ok" = xyes])
|
AM_CONDITIONAL([COND_THREADS], [test "x$ax_pthread_ok" = xyes])
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef MYTHREAD_H
|
||||||
|
#define MYTHREAD_H
|
||||||
|
|
||||||
#include "sysdefs.h"
|
#include "sysdefs.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,19 +22,23 @@
|
||||||
// Using pthreads //
|
// Using pthreads //
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __VMS
|
||||||
|
// Do nothing on OpenVMS. It doesn't have pthread_sigmask().
|
||||||
|
#define mythread_sigmask(how, set, oset) do { } while (0)
|
||||||
|
#else
|
||||||
/// \brief Set the process signal mask
|
/// \brief Set the process signal mask
|
||||||
///
|
///
|
||||||
/// If threads are disabled, sigprocmask() is used instead
|
/// If threads are disabled, sigprocmask() is used instead
|
||||||
/// of pthread_sigmask().
|
/// of pthread_sigmask().
|
||||||
#define mythread_sigmask(how, set, oset) \
|
#define mythread_sigmask(how, set, oset) \
|
||||||
pthread_sigmask(how, set, oset)
|
pthread_sigmask(how, set, oset)
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief Call the given function once
|
/// \brief Call the given function once
|
||||||
///
|
///
|
||||||
|
@ -96,7 +103,9 @@ typedef struct {
|
||||||
static inline int
|
static inline int
|
||||||
mythread_cond_init(mythread_cond *mycond)
|
mythread_cond_init(mythread_cond *mycond)
|
||||||
{
|
{
|
||||||
#if defined(_POSIX_CLOCK_SELECTION) && defined(_POSIX_MONOTONIC_CLOCK)
|
#ifdef HAVE_CLOCK_GETTIME
|
||||||
|
// NOTE: HAVE_DECL_CLOCK_MONOTONIC is always defined to 0 or 1.
|
||||||
|
# if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && HAVE_DECL_CLOCK_MONOTONIC
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
pthread_condattr_t condattr;
|
pthread_condattr_t condattr;
|
||||||
|
|
||||||
|
@ -119,9 +128,11 @@ mythread_cond_init(mythread_cond *mycond)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If anything above fails, fall back to the default CLOCK_REALTIME.
|
// If anything above fails, fall back to the default CLOCK_REALTIME.
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
mycond->clk_id = CLOCK_REALTIME;
|
mycond->clk_id = CLOCK_REALTIME;
|
||||||
|
#endif
|
||||||
|
|
||||||
return pthread_cond_init(&mycond->cond, NULL);
|
return pthread_cond_init(&mycond->cond, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,11 +144,21 @@ mythread_cond_init(mythread_cond *mycond)
|
||||||
static inline void
|
static inline void
|
||||||
mythread_cond_abstime(const mythread_cond *mycond, struct timespec *ts)
|
mythread_cond_abstime(const mythread_cond *mycond, struct timespec *ts)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_CLOCK_GETTIME
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
clock_gettime(mycond->clk_id, &now);
|
clock_gettime(mycond->clk_id, &now);
|
||||||
|
|
||||||
ts->tv_sec += now.tv_sec;
|
ts->tv_sec += now.tv_sec;
|
||||||
ts->tv_nsec += now.tv_nsec;
|
ts->tv_nsec += now.tv_nsec;
|
||||||
|
#else
|
||||||
|
(void)mycond;
|
||||||
|
|
||||||
|
struct timeval now;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
|
||||||
|
ts->tv_sec += now.tv_sec;
|
||||||
|
ts->tv_nsec += now.tv_usec * 1000L;
|
||||||
|
#endif
|
||||||
|
|
||||||
// tv_nsec must stay in the range [0, 999_999_999].
|
// tv_nsec must stay in the range [0, 999_999_999].
|
||||||
if (ts->tv_nsec >= 1000000000L) {
|
if (ts->tv_nsec >= 1000000000L) {
|
||||||
|
@ -200,3 +221,5 @@ do { \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue