ruby-changes:26136
From: tarui <ko1@a...>
Date: Wed, 5 Dec 2012 03:38:32 +0900 (JST)
Subject: [ruby-changes:26136] tarui:r38193 (trunk): * vm_core.h (RUBY_VM_CHECK_INTS_BLOCKING): check async queue everytime.
tarui 2012-12-05 03:38:21 +0900 (Wed, 05 Dec 2012) New Revision: 38193 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38193 Log: * vm_core.h (RUBY_VM_CHECK_INTS_BLOCKING): check async queue everytime. * thread.c (sleep_forever): check RUBY_VM_CHECK_INTS_BLOCKING first. * thread.c (sleep_timeval): ditto. * test/ruby/test_thread.rb (test_async_interrupt_blocking): add a test exceptions are correctly defared and raised on :on_blocking context. Modified files: trunk/ChangeLog trunk/test/ruby/test_thread.rb trunk/thread.c trunk/vm_core.h Index: ChangeLog =================================================================== --- ChangeLog (revision 38192) +++ ChangeLog (revision 38193) @@ -1,3 +1,11 @@ +Wed Dec 5 03:35:37 2012 Masaya Tarui <tarui@r...> + + * vm_core.h (RUBY_VM_CHECK_INTS_BLOCKING): check async queue everytime. + * thread.c (sleep_forever): check RUBY_VM_CHECK_INTS_BLOCKING first. + * thread.c (sleep_timeval): ditto. + * test/ruby/test_thread.rb (test_async_interrupt_blocking): add a test + exceptions are correctly defared and raised on :on_blocking context. + Wed Dec 5 02:36:10 2012 Nobuyoshi Nakada <nobu@r...> * common.mk, defs/id.def, template/id.c.tmpl: generate id.c as well as id.h. Index: vm_core.h =================================================================== --- vm_core.h (revision 38192) +++ vm_core.h (revision 38193) @@ -889,11 +889,16 @@ void rb_thread_lock_unlock(rb_thread_lock_t *); void rb_thread_lock_destroy(rb_thread_lock_t *); -#define RUBY_VM_CHECK_INTS_BLOCKING(th) do { \ - if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(th))) { \ - rb_threadptr_execute_interrupts(th, 1); \ - } \ -} while (0) +#define RUBY_VM_CHECK_INTS_BLOCKING(th) do { \ + if (UNLIKELY(!rb_threadptr_async_errinfo_empty_p(th))) { \ + th->async_errinfo_queue_checked = 0; \ + RUBY_VM_SET_INTERRUPT(th); \ + rb_threadptr_execute_interrupts(th, 1); \ + } \ + else if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(th))) { \ + rb_threadptr_execute_interrupts(th, 1); \ + } \ + } while (0) #define RUBY_VM_CHECK_INTS(th) do { \ if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(th))) { \ Index: thread.c =================================================================== --- thread.c (revision 38192) +++ thread.c (revision 38193) @@ -69,6 +69,7 @@ static double timeofday(void); static int rb_threadptr_dead(rb_thread_t *th); static void rb_check_deadlock(rb_vm_t *vm); +static int rb_threadptr_async_errinfo_empty_p(rb_thread_t *th); #define eKillSignal INT2FIX(0) #define eTerminateSignal INT2FIX(1) @@ -888,7 +889,8 @@ enum rb_thread_status status = deadlockable ? THREAD_STOPPED_FOREVER : THREAD_STOPPED; th->status = status; - do { + RUBY_VM_CHECK_INTS_BLOCKING(th); + while (th->status == status) { if (deadlockable) { th->vm->sleeper++; rb_check_deadlock(th->vm); @@ -898,7 +900,9 @@ th->vm->sleeper--; } RUBY_VM_CHECK_INTS_BLOCKING(th); - } while (spurious_check && th->status == status); + if(!spurious_check) + break; + } th->status = prev_status; } @@ -932,7 +936,8 @@ } th->status = THREAD_STOPPED; - do { + RUBY_VM_CHECK_INTS_BLOCKING(th); + while (th->status == THREAD_STOPPED) { native_sleep(th, &tv); RUBY_VM_CHECK_INTS_BLOCKING(th); getclockofday(&tvn); @@ -946,7 +951,9 @@ --tv.tv_sec; tv.tv_usec += 1000000; } - } while (spurious_check && th->status == THREAD_STOPPED); + if(!spurious_check) + break; + } th->status = prev_status; } Index: test/ruby/test_thread.rb =================================================================== --- test/ruby/test_thread.rb (revision 38192) +++ test/ruby/test_thread.rb (revision 38193) @@ -563,6 +563,30 @@ Thread.async_interrupt_timing([]) {} # array } end + + def test_async_interrupt_blocking + r=:ok + e=Class.new(Exception) + th_s = Thread.current + begin + th = Thread.start{ + Thread.async_interrupt_timing(Object => :on_blocking){ + begin + Thread.current.raise RuntimeError + sleep + ensure + th_s.raise e + end + } + } + sleep 1 + r=:ng + th.raise RuntimeError + th.join + rescue e + end + assert_equal(:ok,r) + end def test_async_interrupted? q = Queue.new -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/