mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* thread.c (do_select): fix to iterate select().
on cygwin/mswin32, iterate in unblocking region. * thread.c (rb_thread_select): don't iterate on this function. (iterate in do_select). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11722 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
da06c63c66
commit
f2586498f3
2 changed files with 85 additions and 91 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Wed Feb 14 12:58:38 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* thread.c (do_select): fix to iterate select().
|
||||||
|
on cygwin/mswin32, iterate in unblocking region.
|
||||||
|
|
||||||
|
* thread.c (rb_thread_select): don't iterate on this function.
|
||||||
|
(iterate in do_select).
|
||||||
|
|
||||||
Wed Feb 14 11:39:18 2007 Koichi Sasada <ko1@atdot.net>
|
Wed Feb 14 11:39:18 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* thread.c (set_unblock_function): fix function interface.
|
* thread.c (set_unblock_function): fix function interface.
|
||||||
|
|
168
thread.c
168
thread.c
|
@ -1641,80 +1641,120 @@ static int
|
||||||
do_select(int n, fd_set *read, fd_set *write, fd_set *except,
|
do_select(int n, fd_set *read, fd_set *write, fd_set *except,
|
||||||
struct timeval *timeout)
|
struct timeval *timeout)
|
||||||
{
|
{
|
||||||
int result, lerrno = 0;
|
int result, lerrno;
|
||||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
|
||||||
/* polling port */
|
|
||||||
fd_set orig_read, orig_write, orig_except;
|
fd_set orig_read, orig_write, orig_except;
|
||||||
struct timeval wait_100ms, *wait;
|
|
||||||
|
|
||||||
wait_100ms.tv_sec = 0;
|
#ifndef linux
|
||||||
wait_100ms.tv_usec = 100 * 1000; /* 100 ms */
|
double limit;
|
||||||
wait = (timeout == 0 || cmp_tv(&wait_100ms, timeout) > 0) ? &wait_100ms : timeout;
|
struct timeval wait_rest;
|
||||||
|
|
||||||
do {
|
if (timeout) {
|
||||||
if (read) orig_read = *read;
|
limit = timeofday() +
|
||||||
if (write) orig_write = *write;
|
(double)timeout->tv_sec+(double)timeout->tv_usec*1e-6;
|
||||||
if (except) orig_except = *except;
|
wait_rest = *timeout;
|
||||||
|
timeout = &wait_rest;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
BLOCKING_REGION({
|
if (read) orig_read = *read;
|
||||||
result = select(n, read, write, except, wait);
|
if (write) orig_write = *write;
|
||||||
if (result < 0) lerrno = errno;
|
if (except) orig_except = *except;
|
||||||
}, 0);
|
|
||||||
|
|
||||||
if (result != 0) break;
|
retry:
|
||||||
if (read) *read = orig_read;
|
lerrno = 0;
|
||||||
if (write) *write = orig_write;
|
|
||||||
if (except) *except = orig_except;
|
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||||
wait = &wait_100ms;
|
{
|
||||||
} while (timeout == 0 || subst(timeout, &wait_100ms));
|
/* polling duration: 100ms */
|
||||||
|
struct timeval wait_100ms, *wait;
|
||||||
|
wait_100ms.tv_sec = 0;
|
||||||
|
wait_100ms.tv_usec = 100 * 1000; /* 100 ms */
|
||||||
|
|
||||||
|
do {
|
||||||
|
wait = (timeout == 0 || cmp_tv(&wait_100ms, timeout) > 0) ? &wait_100ms : timeout;
|
||||||
|
BLOCKING_REGION({
|
||||||
|
do {
|
||||||
|
result = select(n, read, write, except, wait);
|
||||||
|
if (result < 0) lerrno = errno;
|
||||||
|
if (result != 0) break;
|
||||||
|
|
||||||
|
if (read) *read = orig_read;
|
||||||
|
if (write) *write = orig_write;
|
||||||
|
if (except) *except = orig_except;
|
||||||
|
wait = &wait_100ms;
|
||||||
|
} while (__th->interrupt_flag == 0 && (timeout == 0 || subst(timeout, &wait_100ms)));
|
||||||
|
}, 0);
|
||||||
|
} while (result == 0 && (timeout == 0 || subst(timeout, &wait_100ms)));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
BLOCKING_REGION({
|
BLOCKING_REGION({
|
||||||
result = select(n, read, write, except, timeout);
|
result = select(n, read, write, except, timeout);
|
||||||
if (result < 0) lerrno = errno;
|
if (result < 0) lerrno = errno;
|
||||||
}, ubf_select);
|
}, ubf_select);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
errno = lerrno;
|
errno = lerrno;
|
||||||
|
|
||||||
|
if (result < 0) {
|
||||||
|
if (errno == EINTR
|
||||||
|
#ifdef ERESTART
|
||||||
|
|| errno == ERESTART
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
if (read) *read = orig_read;
|
||||||
|
if (write) *write = orig_write;
|
||||||
|
if (except) *except = orig_except;
|
||||||
|
#ifndef linux
|
||||||
|
if (timeout) {
|
||||||
|
double d = limit - timeofday();
|
||||||
|
|
||||||
|
wait_rest.tv_sec = (unsigned int)d;
|
||||||
|
wait_rest.tv_usec = (long)((d-(double)wait_rest.tv_sec)*1e6);
|
||||||
|
if (wait_rest.tv_sec < 0) wait_rest.tv_sec = 0;
|
||||||
|
if (wait_rest.tv_usec < 0) wait_rest.tv_usec = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_bug("fatal error on select() - errno: %d\n", lerrno);
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rb_thread_wait_fd_rw(int fd, char c)
|
rb_thread_wait_fd_rw(int fd, int read)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
thread_debug("rb_thread_wait_fd_rw (%d, %c)\n", fd, c);
|
thread_debug("rb_thread_wait_fd_rw(%d, %s)\n", fd, read ? "read" : "write");
|
||||||
|
|
||||||
while (result <= 0) {
|
while (result <= 0) {
|
||||||
rb_fdset_t set;
|
rb_fdset_t set;
|
||||||
rb_fd_init(&set);
|
rb_fd_init(&set);
|
||||||
FD_SET(fd, &set);
|
FD_SET(fd, &set);
|
||||||
|
|
||||||
switch(c) {
|
if (read) {
|
||||||
case 'r':
|
|
||||||
result = do_select(fd + 1, rb_fd_ptr(&set), 0, 0, 0);
|
result = do_select(fd + 1, rb_fd_ptr(&set), 0, 0, 0);
|
||||||
break;
|
}
|
||||||
|
else {
|
||||||
case'w':
|
|
||||||
result = do_select(fd + 1, 0, rb_fd_ptr(&set), 0, 0);
|
result = do_select(fd + 1, 0, rb_fd_ptr(&set), 0, 0);
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
rb_bug("unknown wait type: %c", c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_debug("rb_thread_wait_fd_rw (%d, %c): done\n", fd, c);
|
thread_debug("rb_thread_wait_fd_rw(%d, %s): done\n", fd, read ? "read" : "write");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_thread_wait_fd(int fd)
|
rb_thread_wait_fd(int fd)
|
||||||
{
|
{
|
||||||
rb_thread_wait_fd_rw(fd, 'r');
|
rb_thread_wait_fd_rw(fd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rb_thread_fd_writable(int fd)
|
rb_thread_fd_writable(int fd)
|
||||||
{
|
{
|
||||||
rb_thread_wait_fd_rw(fd, 'w');
|
rb_thread_wait_fd_rw(fd, 0);
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1722,13 +1762,6 @@ int
|
||||||
rb_thread_select(int max, fd_set * read, fd_set * write, fd_set * except,
|
rb_thread_select(int max, fd_set * read, fd_set * write, fd_set * except,
|
||||||
struct timeval *timeout)
|
struct timeval *timeout)
|
||||||
{
|
{
|
||||||
struct timeval *tvp = timeout;
|
|
||||||
int n;
|
|
||||||
#ifndef linux
|
|
||||||
double limit;
|
|
||||||
struct timeval tv;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!read && !write && !except) {
|
if (!read && !write && !except) {
|
||||||
if (!timeout) {
|
if (!timeout) {
|
||||||
rb_thread_sleep_forever();
|
rb_thread_sleep_forever();
|
||||||
|
@ -1737,57 +1770,10 @@ rb_thread_select(int max, fd_set * read, fd_set * write, fd_set * except,
|
||||||
rb_thread_wait_for(*timeout);
|
rb_thread_wait_for(*timeout);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
#ifndef linux
|
return do_select(max, read, write, except, timeout);
|
||||||
if (timeout) {
|
|
||||||
limit = timeofday() +
|
|
||||||
(double)timeout->tv_sec + (double)timeout->tv_usec * 1e-6;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef linux
|
|
||||||
if (timeout) {
|
|
||||||
tv = *timeout;
|
|
||||||
tvp = &tv;
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
tvp = timeout;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
#ifndef linux
|
|
||||||
fd_set orig_read, orig_write, orig_except;
|
|
||||||
if (read) orig_read = *read;
|
|
||||||
if (write) orig_write = *write;
|
|
||||||
if (except) orig_except = *except;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
n = do_select(max, read, write, except, tvp);
|
|
||||||
|
|
||||||
if (n < 0) {
|
|
||||||
switch (errno) {
|
|
||||||
case EINTR:
|
|
||||||
#ifdef ERESTART
|
|
||||||
case ERESTART:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef linux
|
|
||||||
if (timeout) {
|
|
||||||
double d = limit - timeofday();
|
|
||||||
tv = double2timeval(d);
|
|
||||||
}
|
|
||||||
if (read) *read = orig_read;
|
|
||||||
if (write) *write = orig_write;
|
|
||||||
if (except) *except = orig_except;
|
|
||||||
#endif
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue