Permalink
Browse files

workaround for systems not providing pselect

using a mix of good old select and sigprocmask

Signed-off-by: Jérémie Courrèges-Anglas <jca@wxcvbn.org>
  • Loading branch information...
1 parent fbd2d18 commit 24b078a5a126fc7c7c207747d5f2e20022264e9f Jérémie Courrèges-Anglas committed Apr 16, 2013
Showing with 20 additions and 3 deletions.
  1. +1 −1 configure.ac
  2. +19 −2 src/util/select.h
View
@@ -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.])])
View
@@ -118,25 +118,42 @@ class Select {
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 ) );
memcpy( &error_fds, &all_fds, sizeof( error_fds ) );
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. */

0 comments on commit 24b078a

Please sign in to comment.