diff --git a/configure.ac b/configure.ac index 5be21c8..11153ea 100644 --- a/configure.ac +++ b/configure.ac @@ -195,7 +195,7 @@ AC_TYPE_UINTPTR_T # Checks for library functions. AC_FUNC_FORK AC_FUNC_MBRTOWC -AC_CHECK_FUNCS([gettimeofday setrlimit inet_ntoa iswprint memchr memset nl_langinfo posix_memalign setenv setlocale sigaction socket strchr strdup strncasecmp strtok strerror strtol wcwidth cfmakeraw]) +AC_CHECK_FUNCS([gettimeofday setrlimit inet_ntoa iswprint memchr memset nl_langinfo posix_memalign setenv setlocale sigaction socket strchr strdup strncasecmp strtok strerror strtol wcwidth cfmakeraw pselect]) AC_SEARCH_LIBS([clock_gettime], [rt], [AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Define if clock_gettime is available.])]) diff --git a/src/util/select.h b/src/util/select.h index dc06716..6d9922f 100644 --- a/src/util/select.h +++ b/src/util/select.h @@ -118,6 +118,7 @@ public: fatal_assert( 0 == sigaction( signum, &sa, NULL ) ); } + /* timeout unit: milliseconds; negative timeout means wait forever */ int select( int timeout ) { memcpy( &read_fds, &all_fds, sizeof( read_fds ) ); @@ -125,18 +126,34 @@ public: clear_got_signal(); got_any_signal = 0; +#ifdef HAVE_PSELECT struct timespec ts; struct timespec *tsp = NULL; if ( timeout >= 0 ) { - // timeout in milliseconds ts.tv_sec = timeout / 1000; ts.tv_nsec = 1000000 * (long( timeout ) % 1000); tsp = &ts; } - // negative timeout means wait forever int ret = ::pselect( max_fd + 1, &read_fds, NULL, &error_fds, tsp, &empty_sigset ); +#else + struct timeval tv; + struct timeval *tvp = NULL; + sigset_t old_sigset; + + if ( timeout >= 0 ) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = 1000 * (long( timeout ) % 1000); + tvp = &tv; + } + + int ret = sigprocmask( SIG_SETMASK, &empty_sigset, &old_sigset ); + if ( ret != -1 ) { + ret = ::select( max_fd + 1, &read_fds, NULL, &error_fds, tvp ); + sigprocmask( SIG_SETMASK, &old_sigset, NULL ); + } +#endif if ( ( ret == -1 ) && ( errno == EINTR ) ) { /* The user should process events as usual. */