ruby-changes:6578
From: nobu <ko1@a...>
Date: Thu, 17 Jul 2008 04:19:54 +0900 (JST)
Subject: [ruby-changes:6578] Ruby:r18094 (trunk): * thread.c (thread_start_func_2): wake up joining threads.
nobu 2008-07-17 04:19:36 +0900 (Thu, 17 Jul 2008) New Revision: 18094 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=18094 Log: * thread.c (thread_start_func_2): wake up joining threads. * thread.c (sleep_forever, sleep_timeval): return when interrupted. [ruby-dev:35542] * thread.c (timer_thread_function): restore main thread status. [ruby-core:17270] Modified files: trunk/ChangeLog trunk/thread.c trunk/thread_pthread.c trunk/thread_win32.c Index: thread_win32.c =================================================================== --- thread_win32.c (revision 18093) +++ thread_win32.c (revision 18094) @@ -204,9 +204,8 @@ } static void -native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable) +native_sleep(rb_thread_t *th, struct timeval *tv) { - int prev_status = th->status; DWORD msec; if (tv) { @@ -216,15 +215,6 @@ msec = INFINITE; } - if (!tv && deadlockable) { - th->status = THREAD_STOPPED_FOREVER; - th->vm->sleeper++; - rb_check_deadlock(th->vm); - } - else { - th->status = THREAD_STOPPED; - } - GVL_UNLOCK_BEGIN(); { DWORD ret; @@ -249,9 +239,6 @@ native_mutex_unlock(&th->interrupt_lock); } GVL_UNLOCK_END(); - th->status = prev_status; - if (!tv && deadlockable) th->vm->sleeper--; - RUBY_VM_CHECK_INTS(); } static int Index: ChangeLog =================================================================== --- ChangeLog (revision 18093) +++ ChangeLog (revision 18094) @@ -1,3 +1,13 @@ +Thu Jul 17 04:19:33 2008 Nobuyoshi Nakada <nobu@r...> + + * thread.c (thread_start_func_2): wake up joining threads. + + * thread.c (sleep_forever, sleep_timeval): return when interrupted. + [ruby-dev:35542] + + * thread.c (timer_thread_function): restore main thread status. + [ruby-core:17270] + Thu Jul 17 01:27:38 2008 Yusuke Endoh <mame@t...> * io.c (appendline): remove invalid access. Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 18093) +++ thread_pthread.c (revision 18094) @@ -493,9 +493,8 @@ #endif static void -native_sleep(rb_thread_t *th, struct timeval *tv, int deadlockable) +native_sleep(rb_thread_t *th, struct timeval *tv) { - int prev_status = th->status; struct timespec ts; struct timeval tvn; @@ -509,15 +508,6 @@ } } - if (!tv && deadlockable) { - th->status = THREAD_STOPPED_FOREVER; - th->vm->sleeper++; - rb_check_deadlock(th->vm); - } - else { - th->status = THREAD_STOPPED; - } - thread_debug("native_sleep %ld\n", tv ? tv->tv_sec : -1); GVL_UNLOCK_BEGIN(); { @@ -555,9 +545,6 @@ pthread_mutex_unlock(&th->interrupt_lock); } GVL_UNLOCK_END(); - th->status = prev_status; - if (!tv && deadlockable) th->vm->sleeper--; - RUBY_VM_CHECK_INTS(); thread_debug("native_sleep done\n"); } Index: thread.c =================================================================== --- thread.c (revision 18093) +++ thread.c (revision 18094) @@ -105,7 +105,7 @@ #define BLOCKING_REGION(exec, ubf, ubfarg) do { \ rb_thread_t *__th = GET_THREAD(); \ - int __prev_status = __th->status; \ + enum rb_thread_status __prev_status = __th->status; \ struct rb_unblock_callback __oldubf; \ set_unblock_function(__th, ubf, ubfarg, &__oldubf); \ __th->status = THREAD_STOPPED; \ @@ -413,6 +413,11 @@ while (join_th) { if (join_th == main_th) errinfo = Qnil; rb_thread_interrupt(join_th); + switch (join_th->status) { + case THREAD_STOPPED: case THREAD_STOPPED_FOREVER: + join_th->status = THREAD_RUNNABLE; + default: break; + } join_th = join_th->join_list_next; } if (th != main_th) rb_check_deadlock(th->vm); @@ -714,7 +719,21 @@ static void sleep_forever(rb_thread_t *th, int deadlockable) { - native_sleep(th, 0, deadlockable); + enum rb_thread_status prev_status = th->status; + + th->status = deadlockable ? THREAD_STOPPED_FOREVER : THREAD_STOPPED; + do { + if (deadlockable) { + th->vm->sleeper++; + rb_check_deadlock(th->vm); + } + native_sleep(th, 0); + if (deadlockable) { + th->vm->sleeper--; + } + RUBY_VM_CHECK_INTS(); + } while (th->status == THREAD_STOPPED_FOREVER); + th->status = prev_status; } static void @@ -736,7 +755,33 @@ static void sleep_timeval(rb_thread_t *th, struct timeval tv) { - native_sleep(th, &tv, 0); + struct timeval to, tvn; + enum rb_thread_status prev_status = th->status; + + getclockofday(&to); + to.tv_sec += tv.tv_sec; + if ((to.tv_usec += tv.tv_usec) >= 1000000) { + to.tv_sec++; + to.tv_usec -= 1000000; + } + + th->status = THREAD_STOPPED; + do { + native_sleep(th, &tv); + RUBY_VM_CHECK_INTS(); + getclockofday(&tvn); + if (to.tv_sec < tvn.tv_sec) break; + if (to.tv_sec == tvn.tv_sec && to.tv_usec <= tvn.tv_usec) break; + thread_debug("sleep_timeval: %ld.%.6ld > %ld.%.6ld\n", + (long)to.tv_sec, to.tv_usec, + (long)tvn.tv_sec, tvn.tv_usec); + tv.tv_sec = to.tv_sec - tvn.tv_sec; + if ((tv.tv_usec = to.tv_usec - tvn.tv_usec) < 0) { + --tv.tv_sec; + tv.tv_usec += 1000000; + } + } while (th->status == THREAD_STOPPED); + th->status = prev_status; } void @@ -789,29 +834,7 @@ rb_thread_wait_for(struct timeval time) { rb_thread_t *th = GET_THREAD(); - struct timeval to, tvn; - - getclockofday(&to); - to.tv_sec += time.tv_sec; - if ((to.tv_usec += time.tv_usec) >= 1000000) { - to.tv_sec++; - to.tv_usec -= 1000000; - } - - for (;;) { - sleep_timeval(th, time); - getclockofday(&tvn); - if (to.tv_sec < tvn.tv_sec) break; - if (to.tv_sec == tvn.tv_sec && to.tv_usec <= tvn.tv_usec) break; - thread_debug("sleep_timeval: %ld.%.6ld > %ld.%.6ld\n", - (long)to.tv_sec, to.tv_usec, - (long)tvn.tv_sec, tvn.tv_usec); - time.tv_sec = to.tv_sec - tvn.tv_sec; - if ((time.tv_usec = to.tv_usec - tvn.tv_usec) < 0) { - --time.tv_sec; - time.tv_usec += 1000000; - } - } + sleep_timeval(th, time); } void @@ -913,7 +936,7 @@ { if (th->raised_flag) return; while (th->interrupt_flag) { - int status = th->status; + enum rb_thread_status status = th->status; th->status = THREAD_RUNNABLE; th->interrupt_flag = 0; @@ -1161,6 +1184,9 @@ rb_raise(rb_eThreadError, "killed thread"); } rb_thread_ready(th); + if (th->status != THREAD_TO_KILL) { + th->status = THREAD_RUNNABLE; + } return thread; } @@ -2114,10 +2140,15 @@ /* check signal */ if (vm->buffered_signal_size && vm->main_thread->exec_signal == 0) { - vm->main_thread->exec_signal = rb_get_next_signal(vm); + rb_thread_t *mth = vm->main_thread; + enum rb_thread_status prev_status = mth->status; + mth->exec_signal = rb_get_next_signal(vm); + thread_debug("main_thread: %s\n", thread_status_name(prev_status)); thread_debug("buffered_signal_size: %ld, sig: %d\n", (long)vm->buffered_signal_size, vm->main_thread->exec_signal); - rb_thread_interrupt(vm->main_thread); + if (mth->status != THREAD_KILLED) mth->status = THREAD_RUNNABLE; + rb_thread_interrupt(mth); + mth->status = prev_status; } #if 0 @@ -2635,7 +2666,7 @@ while (mutex->th != th) { int interrupted; - int prev_status = th->status; + enum rb_thread_status prev_status = th->status; int last_thread = 0; struct rb_unblock_callback oldubf; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/