#176: timeout fails to raise a Timeout::Error ---------------------------------+------------------------------------------ Reporter: acangiano@… | Owner: lsansonetti@… Type: defect | Status: new Priority: major | Milestone: Component: MacRuby | Keywords: ---------------------------------+------------------------------------------ Comment(by watson1978@…): The following patch seems to work well. {{{ #!diff diff --git a/lib/timeout.rb b/lib/timeout.rb index 297b769..274f843 100644 --- a/lib/timeout.rb +++ b/lib/timeout.rb @@ -40,11 +40,14 @@ module Timeout # Note that this is both a method of module Timeout, so you can 'include Timeout' # into your classes so they have a #timeout method, as well as a module method, # so you can call it directly as Timeout.timeout(). - def timeout(sec, klass = nil) #:yield: +sec+ + def timeout(sec, klass = nil, &block) #:yield: +sec+ return yield(sec) if sec == nil or sec.zero? exception = klass || Class.new(ExitException) begin - x = Thread.current + val = nil + x = Thread.start { + val = block.call(sec) + } y = Thread.start { begin sleep sec @@ -54,7 +57,8 @@ module Timeout x.raise exception, "execution expired" if x.alive? end } - return yield(sec) + x.join + return val rescue exception => e rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o (bt = e.backtrace).reject! {|m| rej =~ m} diff --git a/thread.c b/thread.c index 6659d06..8a3e715 100644 --- a/thread.c +++ b/thread.c @@ -166,6 +166,9 @@ thread_join_m(VALUE self, SEL sel, int argc, VALUE *argv) ts.tv_sec = 0; ts.tv_nsec = 10000000; while (t->status != THREAD_DEAD) { + if (t->status == THREAD_KILLED && t->exception != Qnil) { + break; + } nanosleep(&ts, NULL); pthread_yield_np(); } diff --git a/vm.cpp b/vm.cpp index d86cc1c..6f664b3 100644 --- a/vm.cpp +++ b/vm.cpp @@ -4654,6 +4654,7 @@ rb_vm_thread_raise(rb_vm_thread_t *t, VALUE exc) // XXX we should lock here RoxorVM *vm = (RoxorVM *)t->vm; vm->push_current_exception(exc); + GC_WB(&t->exception, exc); rb_vm_thread_cancel(t); } }}} -- Ticket URL: <http://www.macruby.org/trac/ticket/176#comment:6> MacRuby <http://macruby.org/>