diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-05-18 04:32:13 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-05-18 04:32:13 +0000 |
commit | a62935cf06b9ee2ec72c749c732c226a18f4d389 (patch) | |
tree | b859df6a5f636b58fe78cbc86d5b9921586d8b2a /eval.c | |
parent | 3e51a5b1b5a953e4705adc924355ffdc83b25472 (diff) |
2000-05-18
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@699 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 48 |
1 files changed, 37 insertions, 11 deletions
@@ -67,6 +67,8 @@ struct timeval { #include <sys/resource.h> #endif +#include <sys/stat.h> + VALUE rb_cProc; static VALUE rb_cBinding; static VALUE proc_call _((VALUE,VALUE)); @@ -6284,6 +6286,7 @@ struct thread { fd_set readfds; fd_set writefds; fd_set exceptfds; + int select_value; double delay; thread_t join; @@ -6681,6 +6684,23 @@ intersect_fds(dst, src, max) return Qfalse; } +static int +find_bad_fds(dst, src, max) + fd_set *dst, *src; + int max; +{ + struct stat s; + int i, test = Qfalse; + + for (i=0; i<=max; i++) { + if (FD_ISSET(i, src) && !FD_ISSET(i, dst)) { + FD_CLR(i, src); + test = Qtrue; + } + } + return test; +} + void rb_thread_schedule() { @@ -6738,7 +6758,7 @@ rb_thread_schedule() copy_fds(&exceptfds, &th->exceptfds, th->fd); if (max < th->fd) max = th->fd; need_select = 1; - th->fd = 0; + th->select_value = 0; } if (th->wait_for & WAIT_TIME) { if (th->delay <= now) { @@ -6777,15 +6797,21 @@ rb_thread_schedule() n = select(max+1, &readfds, &writefds, &exceptfds, delay_ptr); if (n < 0) { if (rb_trap_pending) rb_trap_exec(); - switch (errno) { - case EBADF: - /* xxx */ - case ENOMEM: - n = 0; - break; - default: - goto select_err; + if (errno = EINTR) goto select_err; + FOREACH_THREAD(th) { + if (th->wait_for & WAIT_SELECT) { + int v = 0; + + v |= find_bad_fds(&readfds, &th->readfds, th->fd); + v |= find_bad_fds(&writefds, &th->writefds, th->fd); + v |= find_bad_fds(&exceptfds, &th->exceptfds, th->fd); + if (v) { + th->select_value = n; + n = max; + } + } } + END_FOREACH(th); } if (n > 0) { /* Some descriptors are ready. @@ -6809,7 +6835,7 @@ rb_thread_schedule() intersect_fds(&readfds, &th->readfds, max); intersect_fds(&writefds, &th->writefds, max); intersect_fds(&exceptfds, &th->exceptfds, max); - th->fd = n; + th->select_value = n; found = 1; } } @@ -7018,7 +7044,7 @@ rb_thread_select(max, read, write, except, timeout) if (read) *read = curr_thread->readfds; if (write) *write = curr_thread->writefds; if (except) *except = curr_thread->exceptfds; - return curr_thread->fd; + return curr_thread->select_value; } static VALUE |