* 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:
parent
066eecf53a
commit
4a9883e92f
@ -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>
|
Fri May 6 23:13:43 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
* configure.in: remove nanosleep check. we no longer use it.
|
* configure.in: remove nanosleep check. we no longer use it.
|
||||||
|
@ -1310,7 +1310,7 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall __syscall chroot ge
|
|||||||
dlopen sigprocmask sigaction sigsetjmp _setjmp _longjmp\
|
dlopen sigprocmask sigaction sigsetjmp _setjmp _longjmp\
|
||||||
setsid telldir seekdir fchmod cosh sinh tanh log2 round\
|
setsid telldir seekdir fchmod cosh sinh tanh log2 round\
|
||||||
setuid setgid daemon select_large_fdset setenv unsetenv\
|
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)
|
pread sendfile shutdown sigaltstack dl_iterate_phdr)
|
||||||
|
|
||||||
AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value,
|
AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value,
|
||||||
|
60
thread.c
60
thread.c
@ -2715,12 +2715,41 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t *
|
|||||||
|
|
||||||
#ifdef USE_POLL
|
#ifdef USE_POLL
|
||||||
|
|
||||||
|
|
||||||
/* The same with linux kernel. TODO: make platform independent definition. */
|
/* The same with linux kernel. TODO: make platform independent definition. */
|
||||||
#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
|
#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
|
||||||
#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
|
#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
|
||||||
#define POLLEX_SET (POLLPRI)
|
#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
|
* returns a mask of events
|
||||||
*/
|
*/
|
||||||
@ -2729,17 +2758,25 @@ rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
|
|||||||
{
|
{
|
||||||
struct pollfd fds;
|
struct pollfd fds;
|
||||||
int result, lerrno;
|
int result, lerrno;
|
||||||
double start;
|
double limit = 0;
|
||||||
int timeout = tv ? tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000 : -1;
|
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.fd = fd;
|
||||||
fds.events = (short)events;
|
fds.events = (short)events;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
lerrno = 0;
|
lerrno = 0;
|
||||||
start = timeofday();
|
|
||||||
BLOCKING_REGION({
|
BLOCKING_REGION({
|
||||||
result = poll(&fds, 1, timeout);
|
result = ppoll(&fds, 1, timeout, NULL);
|
||||||
if (result < 0) lerrno = errno;
|
if (result < 0) lerrno = errno;
|
||||||
}, ubf_select, GET_THREAD());
|
}, ubf_select, GET_THREAD());
|
||||||
|
|
||||||
@ -2750,10 +2787,15 @@ retry:
|
|||||||
#ifdef ERESTART
|
#ifdef ERESTART
|
||||||
case ERESTART:
|
case ERESTART:
|
||||||
#endif
|
#endif
|
||||||
if (timeout > 0) {
|
if (timeout) {
|
||||||
timeout -= (timeofday() - start) * 1000;
|
double d = limit - timeofday();
|
||||||
if (timeout < 0)
|
|
||||||
timeout = 0;
|
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;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user