diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-02-14 04:02:12 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-02-14 04:02:12 +0000 |
commit | f2586498f3bb38310f039e7532c034011e2aef82 (patch) | |
tree | 37aa3aa2b86835910079dd192cb60215d9d1b24f | |
parent | da06c63c66cd9901be498ab4a970332fbbeeceeb (diff) | |
download | ruby-f2586498f3bb38310f039e7532c034011e2aef82.tar.gz |
* 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
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | thread.c | 176 |
2 files changed, 89 insertions, 95 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> * thread.c (set_unblock_function): fix function interface. @@ -1641,80 +1641,120 @@ static int do_select(int n, fd_set *read, fd_set *write, fd_set *except, struct timeval *timeout) { - int result, lerrno = 0; -#if defined(__CYGWIN__) || defined(_WIN32) - /* polling port */ + int result, lerrno; fd_set orig_read, orig_write, orig_except; - struct timeval wait_100ms, *wait; - - wait_100ms.tv_sec = 0; - wait_100ms.tv_usec = 100 * 1000; /* 100 ms */ - wait = (timeout == 0 || cmp_tv(&wait_100ms, timeout) > 0) ? &wait_100ms : timeout; - - do { - if (read) orig_read = *read; - if (write) orig_write = *write; - if (except) orig_except = *except; - - BLOCKING_REGION({ - result = select(n, read, write, except, wait); - if (result < 0) lerrno = errno; - }, 0); - - if (result != 0) break; - if (read) *read = orig_read; - if (write) *write = orig_write; - if (except) *except = orig_except; - wait = &wait_100ms; - } while (timeout == 0 || subst(timeout, &wait_100ms)); + +#ifndef linux + double limit; + struct timeval wait_rest; + + if (timeout) { + limit = timeofday() + + (double)timeout->tv_sec+(double)timeout->tv_usec*1e-6; + wait_rest = *timeout; + timeout = &wait_rest; + } +#endif + + if (read) orig_read = *read; + if (write) orig_write = *write; + if (except) orig_except = *except; + + retry: + lerrno = 0; + +#if defined(__CYGWIN__) || defined(_WIN32) + { + /* 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 BLOCKING_REGION({ result = select(n, read, write, except, timeout); if (result < 0) lerrno = errno; }, ubf_select); #endif + 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; } static void -rb_thread_wait_fd_rw(int fd, char c) +rb_thread_wait_fd_rw(int fd, int read) { 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) { rb_fdset_t set; rb_fd_init(&set); FD_SET(fd, &set); - switch(c) { - case 'r': + if (read) { result = do_select(fd + 1, rb_fd_ptr(&set), 0, 0, 0); - break; - - case'w': + } + else { 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 rb_thread_wait_fd(int fd) { - rb_thread_wait_fd_rw(fd, 'r'); + rb_thread_wait_fd_rw(fd, 1); } int rb_thread_fd_writable(int fd) { - rb_thread_wait_fd_rw(fd, 'w'); + rb_thread_wait_fd_rw(fd, 0); return Qtrue; } @@ -1722,13 +1762,6 @@ int rb_thread_select(int max, fd_set * read, fd_set * write, fd_set * except, struct timeval *timeout) { - struct timeval *tvp = timeout; - int n; -#ifndef linux - double limit; - struct timeval tv; -#endif - if (!read && !write && !except) { if (!timeout) { 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); return 0; } - -#ifndef linux - if (timeout) { - limit = timeofday() + - (double)timeout->tv_sec + (double)timeout->tv_usec * 1e-6; + else { + return do_select(max, read, write, except, timeout); } -#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; - } -} /* |