Revision: 1946 http://trac.macosforge.org/projects/ruby/changeset/1946 Author: lsansonetti@apple.com Date: 2009-06-26 23:39:27 -0700 (Fri, 26 Jun 2009) Log Message: ----------- more MT work Modified Paths: -------------- MacRuby/branches/experimental/thread.c MacRuby/branches/experimental/vm.cpp MacRuby/branches/experimental/vm.h Modified: MacRuby/branches/experimental/thread.c =================================================================== --- MacRuby/branches/experimental/thread.c 2009-06-27 06:38:55 UTC (rev 1945) +++ MacRuby/branches/experimental/thread.c 2009-06-27 06:39:27 UTC (rev 1946) @@ -131,31 +131,35 @@ rb_scan_args(argc, argv, "01", &timeout); rb_vm_thread_t *t = GetThreadPtr(self); - if (t->status == THREAD_DEAD) { - return self; - } - - if (timeout == Qnil) { - // No timeout given: block until the thread finishes. - pthread_assert(pthread_join(t->thread, NULL)); - } - else { - // Timeout given: sleep then check if the thread is dead. - // TODO do multiple sleeps instead of only one. - struct timeval tv = rb_time_interval(timeout); - struct timespec ts; - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; - while (ts.tv_nsec >= 1000000000) { - ts.tv_sec += 1; - ts.tv_nsec -= 1000000000; + if (t->status != THREAD_DEAD) { + if (timeout == Qnil) { + // No timeout given: block until the thread finishes. + pthread_assert(pthread_join(t->thread, NULL)); } - nanosleep(&ts, NULL); - if (t->status != THREAD_DEAD) { - return Qnil; + else { + // Timeout given: sleep then check if the thread is dead. + // TODO do multiple sleeps instead of only one. + struct timeval tv = rb_time_interval(timeout); + struct timespec ts; + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; + while (ts.tv_nsec >= 1000000000) { + ts.tv_sec += 1; + ts.tv_nsec -= 1000000000; + } + nanosleep(&ts, NULL); + if (t->status != THREAD_DEAD) { + return Qnil; + } } } + // If the thread was terminated because of an exception, we need to + // propagate it. + if (t->exception != Qnil) { + rb_exc_raise(t->exception); + } + return self; } @@ -570,8 +574,7 @@ { rb_vm_thread_t *t = GetThreadPtr(thread); if (t->status == THREAD_DEAD) { - // TODO should return Qnil in case the thread got an exception. - return Qfalse; + return t->exception == Qnil ? Qfalse : Qnil; } return rb_str_new2(rb_thread_status_cstr(thread)); } Modified: MacRuby/branches/experimental/vm.cpp =================================================================== --- MacRuby/branches/experimental/vm.cpp 2009-06-27 06:38:55 UTC (rev 1945) +++ MacRuby/branches/experimental/vm.cpp 2009-06-27 06:39:27 UTC (rev 1946) @@ -4420,9 +4420,11 @@ GC_WB(&t->value, val); } catch (...) { - // TODO handle thread-level exceptions. - //printf("exception raised inside thread %p\n", pthread_self()); - t->value = Qfalse; + VALUE exc = rb_vm_current_exception(); + if (exc != Qnil) { + GC_WB(&t->exception, exc); + } + t->value = Qnil; } pthread_cleanup_pop(0); @@ -4495,6 +4497,7 @@ t->vm = vm; t->value = Qundef; t->locals = Qnil; + t->exception = Qnil; t->status = THREAD_ALIVE; t->in_cond_wait = false; Modified: MacRuby/branches/experimental/vm.h =================================================================== --- MacRuby/branches/experimental/vm.h 2009-06-27 06:38:55 UTC (rev 1945) +++ MacRuby/branches/experimental/vm.h 2009-06-27 06:39:27 UTC (rev 1946) @@ -103,6 +103,7 @@ rb_vm_thread_status_t status; bool in_cond_wait; VALUE locals; // a Hash object or Qnil + VALUE exception; // killed-by-exception or Qnil } rb_vm_thread_t; typedef struct rb_vm_outer {
participants (1)
-
source_changes@macosforge.org