diff --git a/acinclude.m4 b/acinclude.m4 index 155c47ea..841621f0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -90,6 +90,63 @@ AC_DEFUN([ACX_CHECK_POLL], [ fi ])dnl ACX_CHECK_POLL +dnl See if we need extra libraries for nanosleep +AC_DEFUN([ACX_CHECK_NANOSLEEP], [ + acx_nanosleep_ok=no + acx_nanosleep_list="" + + dnl check if user has set NANOSLEEP_LIBS + save_user_NANOSLEEP_LIBS="$NANOSLEEP_LIBS" + if test x"$NANOSLEEP_LIBS" != x; then + acx_nanosleep_list=user + fi + + dnl check various libraries (including no extra libraries) for + dnl nanosleep. `none' should appear first. + acx_nanosleep_list="none $acx_nanosleep_list rt" + for flag in $acx_nanosleep_list; do + case $flag in + none) + AC_MSG_CHECKING([for nanosleep]) + NANOSLEEP_LIBS="" + ;; + + user) + AC_MSG_CHECKING([for nanosleep in $save_user_NANOSLEEP_LIBS]) + NANOSLEEP_LIBS="$save_user_NANOSLEEP_LIBS" + ;; + + *) + AC_MSG_CHECKING([for nanosleep in -l$flag]) + NANOSLEEP_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + LIBS="$NANOSLEEP_LIBS $LIBS" + AC_TRY_LINK([#include ], + [struct timespec t = { 1, 1000 }; nanosleep(&t, NULL);], + acx_nanosleep_ok=yes, acx_nanosleep_ok=no) + LIBS="$save_LIBS" + AC_MSG_RESULT($acx_nanosleep_ok) + if test x"$acx_nanosleep_ok" = xyes; then + break; + fi + NANOSLEEP_LIBS="" + done + + AC_SUBST(NANOSLEEP_LIBS) + + # execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: + if test x"$acx_nanosleep_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_NANOSLEEP,1,[Define if you have the `nanosleep' function.]),[$1]) + : + else + acx_nanosleep_ok=no + $2 + fi +])dnl ACX_CHECK_POLL + dnl The following macros are from http://www.gnu.org/software/ac-archive/ dnl which distributes them under the following license: dnl diff --git a/configure.in b/configure.in index b92c7539..75ec64de 100644 --- a/configure.in +++ b/configure.in @@ -31,12 +31,13 @@ dnl checks for programs AC_PROG_CXX AC_PROG_RANLIB -dnl checks for libraries -ACX_PTHREAD(,AC_MSG_ERROR(You must have pthreads to compile synergy)) - dnl do checks using C++ AC_LANG_CPLUSPLUS +dnl checks for libraries +ACX_PTHREAD(,AC_MSG_ERROR(You must have pthreads to compile synergy)) +ACX_CHECK_NANOSLEEP + dnl checks for header files AC_HEADER_STDC AC_CHECK_HEADERS([unistd.h sys/time.h]) @@ -83,6 +84,7 @@ dnl checks for system services dnl adjust variables for X11 and pthreads CXXFLAGS="$CXXFLAGS $X_CFLAGS $PTHREAD_CFLAGS" +LIBS="$NANOSLEEP_LIBS $PTHREAD_LIBS $LIBS" AC_OUTPUT([ Makefile diff --git a/lib/mt/CThreadRep.cpp b/lib/mt/CThreadRep.cpp index bc92ba8b..37ff52cf 100644 --- a/lib/mt/CThreadRep.cpp +++ b/lib/mt/CThreadRep.cpp @@ -351,6 +351,17 @@ CThreadRep::doThreadFunc() # include # endif #endif +#if !HAVE_NANOSLEEP +# if HAVE_SYS_SELECT_H +# include +# endif +# if HAVE_SYS_TYPES_H +# include +# endif +# if HAVE_UNISTD_H +# include +# endif +#endif void CThreadRep::init() @@ -378,11 +389,30 @@ CThreadRep::sleep( if (timeout < 0.0) { return; } +#if HAVE_NANOSLEEP struct timespec t; t.tv_sec = (long)timeout; t.tv_nsec = (long)(1000000000.0 * (timeout - (double)t.tv_sec)); while (nanosleep(&t, &t) < 0) testCancel(); +#else + /* emulate nanosleep() with select() */ + CStopwatch timer(true); + double timeLeft = timeout - timer.getTime(); + while (timeLeft > 0.0) { + struct timeval timeout2; + timeout2.tv_sec = static_cast(timeLeft); + timeout2.tv_usec = static_cast(1.0e+6 * (timeLeft - + timeout2.tv_sec)); + select((SELECT_TYPE_ARG1) 0, + SELECT_TYPE_ARG234 NULL, + SELECT_TYPE_ARG234 NULL, + SELECT_TYPE_ARG234 NULL, + SELECT_TYPE_ARG5 &timeout2); + testCancel(); + timeLeft = timeout - timer.getTime(); + } +#endif } void