Feature #4531 » 0001-rb_wait_for_single_fd-use-ppoll-instead-of-poll.patch
| configure.in | ||
|---|---|---|
|
dlopen sigprocmask sigaction sigsetjmp _setjmp _longjmp\
|
||
|
setsid telldir seekdir fchmod cosh sinh tanh log2 round\
|
||
|
setuid setgid daemon select_large_fdset setenv unsetenv\
|
||
|
mktime timegm gmtime_r clock_gettime gettimeofday poll\
|
||
|
mktime timegm gmtime_r clock_gettime gettimeofday ppoll\
|
||
|
pread sendfile shutdown sigaltstack dl_iterate_phdr)
|
||
|
AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value,
|
||
| include/ruby/io.h | ||
|---|---|---|
|
#endif
|
||
|
#include "ruby/config.h"
|
||
|
#if defined(HAVE_POLL)
|
||
|
#if defined(HAVE_PPOLL)
|
||
|
# include <poll.h>
|
||
|
# define RB_WAITFD_IN POLLIN
|
||
|
# define RB_WAITFD_PRI POLLPRI
|
||
| thread.c | ||
|---|---|---|
|
}
|
||
|
/*
|
||
|
* poll() is supported by many OSes, but so far Linux is the only
|
||
|
* one we know of that supports using poll() in all places select()
|
||
|
* would work.
|
||
|
* while poll() is supported by many OSes, Linux is the only one we know of
|
||
|
* that supports using poll() in all places select() would work. We now
|
||
|
* use ppoll() instead of poll() since it offers higher timeouts and
|
||
|
* higher resolution for compatibility with the select()-based implementation.
|
||
|
*/
|
||
|
#if defined(HAVE_POLL) && defined(linux)
|
||
|
# define USE_POLL
|
||
|
#if defined(HAVE_PPOLL) && defined(linux)
|
||
|
# define USE_PPOLL
|
||
|
#endif
|
||
|
#ifdef USE_POLL
|
||
|
#ifdef USE_PPOLL
|
||
|
/* The same with linux kernel. TODO: make platform independent definition. */
|
||
|
#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
|
||
| ... | ... | |
|
{
|
||
|
struct pollfd fds;
|
||
|
int result, lerrno;
|
||
|
double start;
|
||
|
int timeout = tv ? tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000 : -1;
|
||
|
double limit = 0;
|
||
|
struct timespec ts;
|
||
|
struct timespec *timeout = NULL;
|
||
|
if (tv) {
|
||
|
ts.tv_sec = tv->tv_sec;
|
||
|
ts.tv_nsec = tv->tv_usec * 1000;
|
||
|
limit = timeofday();
|
||
|
limit += (double)tv->tv_sec + (double)tv->tv_usec * 1e-6;
|
||
|
timeout = &ts;
|
||
|
}
|
||
|
fds.fd = fd;
|
||
|
fds.events = (short)events;
|
||
|
retry:
|
||
|
lerrno = 0;
|
||
|
start = timeofday();
|
||
|
BLOCKING_REGION({
|
||
|
result = poll(&fds, 1, timeout);
|
||
|
result = ppoll(&fds, 1, timeout, NULL);
|
||
|
if (result < 0) lerrno = errno;
|
||
|
}, ubf_select, GET_THREAD());
|
||
| ... | ... | |
|
#ifdef ERESTART
|
||
|
case ERESTART:
|
||
|
#endif
|
||
|
if (timeout > 0) {
|
||
|
timeout -= (timeofday() - start) * 1000;
|
||
|
if (timeout < 0)
|
||
|
timeout = 0;
|
||
|
if (timeout) {
|
||
|
double d = limit - timeofday();
|
||
|
ts.tv_sec = (long)d;
|
||
|
ts.tv_nsec = (long)((d - (double)ts.tv_sec) * 1e9);
|
||
|
if (ts.tv_sec < 0)
|
||
|
ts.tv_sec = 0;
|
||
|
if (ts.tv_nsec < 0)
|
||
|
ts.tv_nsec = 0;
|
||
|
}
|
||
|
goto retry;
|
||
|
}
|
||
| ... | ... | |
|
return result;
|
||
|
}
|
||
|
#else /* ! USE_POLL - implement rb_io_poll_fd() using select() */
|
||
|
#else /* ! USE_PPOLL - implement rb_io_poll_fd() using select() */
|
||
|
static rb_fdset_t *init_set_fd(int fd, rb_fdset_t *fds)
|
||
|
{
|
||
|
rb_fd_init(fds);
|
||
| ... | ... | |
|
return r;
|
||
|
}
|
||
|
#endif /* ! USE_POLL */
|
||
|
#endif /* ! USE_PPOLL */
|
||
|
/*
|
||
|
* for GC
|
||