diff options
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | eval.c | 64 | ||||
-rw-r--r-- | version.h | 8 |
3 files changed, 55 insertions, 32 deletions
@@ -1,3 +1,18 @@ +Mon Sep 7 19:52:44 2009 Tanaka Akira <akr@fsij.org> + + * eval.c (rb_thread_schedule): need select for WAIT_SELECT, even if + already timeout. [ruby-dev:38971] + (WAIT_DONE): defined for mark threads which can be runnable. + +Mon Sep 7 19:52:44 2009 Tanaka Akira <akr@fsij.org> + + * eval.c (rb_thread_schedule): refine previous change. + +Mon Sep 7 19:52:44 2009 Tanaka Akira <akr@fsij.org> + + * eval.c (rb_thread_schedule): fix condition for making thread + runnable. [ruby-core:23515] + Sun Sep 6 19:47:10 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> * eval.c (rb_exc_raise, rb_exc_fatal): require exception object. @@ -10216,6 +10216,7 @@ extern VALUE rb_last_status; #define WAIT_TIME (1<<2) #define WAIT_JOIN (1<<3) #define WAIT_PID (1<<4) +#define WAIT_DONE (1<<5) /* +infty, for this purpose */ #define DELAY_INFTY 1E30 @@ -11008,7 +11009,6 @@ rb_thread_schedule() rb_thread_t next; /* OK */ rb_thread_t th; rb_thread_t curr; - rb_thread_t th_found = 0; int found = 0; fd_set readfds; @@ -11047,6 +11047,7 @@ rb_thread_schedule() now = -1.0; FOREACH_THREAD_FROM(curr, th) { + th->wait_for &= ~WAIT_DONE; if (!found && th->status <= THREAD_RUNNABLE) { found = 1; } @@ -11079,7 +11080,12 @@ rb_thread_schedule() if (now < 0.0) now = timeofday(); th_delay = th->delay - now; if (th_delay <= 0.0) { - th->status = THREAD_RUNNABLE; + if (th->wait_for & WAIT_SELECT) { + need_select = 1; + } + else { + th->status = THREAD_RUNNABLE; + } found = 1; } else if (th_delay < delay) { @@ -11198,22 +11204,22 @@ rb_thread_schedule() if (n > 0) { now = -1.0; /* Some descriptors are ready. - * Choose a thread which may run next. - * Don't change the status of threads which don't run next. + * The corresponding threads are runnable as next. + * Mark them with WAIT_DONE. + * Don't change the status to runnable here because + * threads which don't run next should not be changed. */ FOREACH_THREAD_FROM(curr, th) { if ((th->wait_for&WAIT_FD) && FD_ISSET(th->fd, &readfds)) { - th_found = th; + th->wait_for |= WAIT_DONE; found = 1; - break; } if ((th->wait_for&WAIT_SELECT) && (match_fds(&readfds, &th->readfds, max) || match_fds(&writefds, &th->writefds, max) || match_fds(&exceptfds, &th->exceptfds, max))) { - th_found = th; + th->wait_for |= WAIT_DONE; found = 1; - break; } } END_FOREACH_FROM(curr, th); @@ -11229,27 +11235,28 @@ rb_thread_schedule() next = th; break; } - if ((th->status == THREAD_RUNNABLE || th == th_found) && th->stk_ptr) { + if ((th->status == THREAD_RUNNABLE || (th->wait_for & WAIT_DONE)) && th->stk_ptr) { if (!next || next->priority < th->priority) { - if (th == th_found) { - th_found->status = THREAD_RUNNABLE; - th_found->wait_for = 0; - if (th->wait_for&WAIT_FD) { - th_found->fd = 0; - } - else { /* th->wait_for&WAIT_SELECT */ - n = intersect_fds(&readfds, &th_found->readfds, max) + - intersect_fds(&writefds, &th_found->writefds, max) + - intersect_fds(&exceptfds, &th_found->exceptfds, max); - th_found->select_value = n; - } - } next = th; } } } END_FOREACH_FROM(curr, th); + if (next && (next->wait_for & WAIT_DONE)) { + next->status = THREAD_RUNNABLE; + if (next->wait_for&WAIT_FD) { + next->fd = 0; + } + else { /* next->wait_for&WAIT_SELECT */ + n = intersect_fds(&readfds, &next->readfds, max) + + intersect_fds(&writefds, &next->writefds, max) + + intersect_fds(&exceptfds, &next->exceptfds, max); + next->select_value = n; + } + next->wait_for = 0; + } + if (!next) { /* raise fatal error to main thread */ curr_thread->node = ruby_current_node; @@ -11259,15 +11266,16 @@ rb_thread_schedule() TRAP_END; } FOREACH_THREAD_FROM(curr, th) { + int wait_for = th->wait_for & ~WAIT_DONE; warn_printf("deadlock 0x%lx: %s:", th->thread, thread_status_name(th->status)); - if (th->wait_for & WAIT_FD) warn_printf("F(%d)", th->fd); - if (th->wait_for & WAIT_SELECT) warn_printf("S"); - if (th->wait_for & WAIT_TIME) warn_printf("T(%f)", th->delay); - if (th->wait_for & WAIT_JOIN) + if (wait_for & WAIT_FD) warn_printf("F(%d)", th->fd); + if (wait_for & WAIT_SELECT) warn_printf("S"); + if (wait_for & WAIT_TIME) warn_printf("T(%f)", th->delay); + if (wait_for & WAIT_JOIN) warn_printf("J(0x%lx)", th->join ? th->join->thread : 0); - if (th->wait_for & WAIT_PID) warn_printf("P"); - if (!th->wait_for) warn_printf("-"); + if (wait_for & WAIT_PID) warn_printf("P"); + if (!wait_for) warn_printf("-"); warn_printf(" %s - %s:%d\n", th==main_thread ? "(main)" : "", th->node->nd_file, nd_line(th->node)); @@ -1,15 +1,15 @@ #define RUBY_VERSION "1.8.7" -#define RUBY_RELEASE_DATE "2009-09-06" +#define RUBY_RELEASE_DATE "2009-09-07" #define RUBY_VERSION_CODE 187 -#define RUBY_RELEASE_CODE 20090906 -#define RUBY_PATCHLEVEL 199 +#define RUBY_RELEASE_CODE 20090907 +#define RUBY_PATCHLEVEL 200 #define RUBY_VERSION_MAJOR 1 #define RUBY_VERSION_MINOR 8 #define RUBY_VERSION_TEENY 7 #define RUBY_RELEASE_YEAR 2009 #define RUBY_RELEASE_MONTH 9 -#define RUBY_RELEASE_DAY 6 +#define RUBY_RELEASE_DAY 7 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[]; |