1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* thread.c (rb_wait_for_single_fd): use ppoll() instead of poll()

if possible. based on a patch from Eric Wong. [ruby-core:36003].



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31450 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
kosaki 2011-05-06 14:58:38 +00:00
parent 066eecf53a
commit 4a9883e92f
3 changed files with 57 additions and 10 deletions

View file

@ -1,3 +1,8 @@
Fri May 6 23:29:47 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
* thread.c (rb_wait_for_single_fd): use ppoll() instead of poll()
if possible. based on a patch from Eric Wong. [ruby-core:36003].
Fri May 6 23:13:43 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
* configure.in: remove nanosleep check. we no longer use it.

View file

@ -1310,7 +1310,7 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall __syscall chroot ge
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 poll ppoll\
pread sendfile shutdown sigaltstack dl_iterate_phdr)
AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value,

View file

@ -2715,12 +2715,41 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t *
#ifdef USE_POLL
/* The same with linux kernel. TODO: make platform independent definition. */
#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
#define POLLEX_SET (POLLPRI)
#define TIMET_MAX (~(time_t)0 <= 0 ? (time_t)((~(unsigned_time_t)0) >> 1) : (time_t)(~(unsigned_time_t)0))
#define TIMET_MIN (~(time_t)0 <= 0 ? (time_t)(((unsigned_time_t)1) << (sizeof(time_t) * CHAR_BIT - 1)) : (time_t)0)
#ifndef HAVE_PPOLL
/* TODO: don't ignore sigmask */
int ppoll(struct pollfd *fds, nfds_t nfds,
const struct timespec *ts, const sigset_t *sigmask)
{
int timeout_ms;
if (ts) {
int tmp, tmp2;
if (ts->tv_sec > TIMET_MAX/1000)
timeout_ms = -1;
else {
tmp = ts->tv_sec * 1000;
tmp2 = tv->tv_nsec / (1000 * 1000);
if (TIMET_MAX - tmp < tmp2)
timeout_ms = -1;
else
timeout_ms = tmp + tmp2;
}
} else
timeout = -1;
return poll(fds, nfds, timeout_ms);
}
#endif
/*
* returns a mask of events
*/
@ -2729,17 +2758,25 @@ rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
{
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());
@ -2750,10 +2787,15 @@ retry:
#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;
}