зеркало из https://github.com/github/ruby.git
* thread.c (rb_wait_for_single_fd): new. poll(2) based backend for rb_wait_for_single_fd().
Now only Linux uses it. The patch was written by Eric Wong. [Ruby 1.9 - Feature #4531] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31420 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
9be37ca7d5
Коммит
249fe0e742
|
@ -1,3 +1,10 @@
|
||||||
|
Wed May 4 10:01:27 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
|
* thread.c (rb_wait_for_single_fd): new. poll(2) based backend for rb_wait_for_single_fd().
|
||||||
|
Now only Linux uses it.
|
||||||
|
|
||||||
|
The patch was written by Eric Wong. [Ruby 1.9 - Feature #4531]
|
||||||
|
|
||||||
Wed May 4 09:56:57 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
Wed May 4 09:56:57 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
* thread.c (rb_wait_for_single_fd): new.
|
* thread.c (rb_wait_for_single_fd): new.
|
||||||
|
|
|
@ -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\
|
mktime timegm gmtime_r clock_gettime gettimeofday poll\
|
||||||
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,
|
||||||
|
|
|
@ -27,9 +27,17 @@ extern "C" {
|
||||||
#include <stdio_ext.h>
|
#include <stdio_ext.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RB_WAITFD_IN 0x001
|
#include "ruby/config.h"
|
||||||
#define RB_WAITFD_PRI 0x002
|
#if defined(HAVE_POLL)
|
||||||
#define RB_WAITFD_OUT 0x004
|
# include <poll.h>
|
||||||
|
# define RB_WAITFD_IN POLLIN
|
||||||
|
# define RB_WAITFD_PRI POLLPRI
|
||||||
|
# define RB_WAITFD_OUT POLLOUT
|
||||||
|
#else
|
||||||
|
# define RB_WAITFD_IN 0x001
|
||||||
|
# define RB_WAITFD_PRI 0x002
|
||||||
|
# define RB_WAITFD_OUT 0x004
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined __GNUC__ && __GNUC__ >= 4
|
#if defined __GNUC__ && __GNUC__ >= 4
|
||||||
#pragma GCC visibility push(default)
|
#pragma GCC visibility push(default)
|
||||||
|
|
58
thread.c
58
thread.c
|
@ -2704,6 +2704,63 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t *
|
||||||
return do_select(max, read, write, except, timeout);
|
return do_select(max, read, write, except, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#if defined(HAVE_POLL) && defined(linux)
|
||||||
|
# define USE_POLL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_POLL
|
||||||
|
/*
|
||||||
|
* returns a mask of events
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
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;
|
||||||
|
|
||||||
|
fds.fd = fd;
|
||||||
|
fds.events = (short)events;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
lerrno = 0;
|
||||||
|
start = timeofday();
|
||||||
|
BLOCKING_REGION({
|
||||||
|
result = poll(&fds, 1, timeout);
|
||||||
|
if (result < 0) lerrno = errno;
|
||||||
|
}, ubf_select, GET_THREAD());
|
||||||
|
|
||||||
|
if (result > 0) {
|
||||||
|
/* remain compatible with select(2)-based implementation */
|
||||||
|
result = (int)(fds.revents & fds.events);
|
||||||
|
return result == 0 ? events : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result < 0) {
|
||||||
|
errno = lerrno;
|
||||||
|
switch (errno) {
|
||||||
|
case EINTR:
|
||||||
|
#ifdef ERESTART
|
||||||
|
case ERESTART:
|
||||||
|
#endif
|
||||||
|
if (timeout > 0) {
|
||||||
|
timeout -= (timeofday() - start) * 1000;
|
||||||
|
if (timeout < 0)
|
||||||
|
timeout = 0;
|
||||||
|
}
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#else /* ! USE_POLL - implement rb_io_poll_fd() using select() */
|
||||||
static rb_fdset_t *init_set_fd(int fd, rb_fdset_t *fds)
|
static rb_fdset_t *init_set_fd(int fd, rb_fdset_t *fds)
|
||||||
{
|
{
|
||||||
rb_fd_init(fds);
|
rb_fd_init(fds);
|
||||||
|
@ -2777,6 +2834,7 @@ rb_wait_for_single_fd(int fd, int events, struct timeval *tv)
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
#endif /* ! USE_POLL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* for GC
|
* for GC
|
||||||
|
|
Загрузка…
Ссылка в новой задаче