#883: Abort occurs when calls Thread#kill, Using 32bit arch. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Comment(by watson1978@…): MacRuby throws a C++'s exception when rb_vm_thread_destructor() is executed after calls pthread_cancel(). [[BR]] When the thread is really dead, can't catch the exception. [[BR]] The thread is dead when executes a cancellation point (nanosleep, pthread_cond_wait, pthread_testcancel, etc). abort did not occur by the following changes, but unfortunately the spec does not do pass X( {{{ #!diff diff --git a/vm.cpp b/vm.cpp index 71d3f8a..2a6bf4d 100644 --- a/vm.cpp +++ b/vm.cpp @@ -4544,6 +4544,7 @@ rb_vm_thread_pre_init(rb_vm_thread_t *t, rb_vm_block_t *body, int argc, t->in_cond_wait = false; t->abort_on_exception = false; t->joined_on_exception = false; + t->canceled = false; t->group = Qnil; // will be set right after t->mutexes = Qnil; @@ -4582,8 +4583,10 @@ rb_thread_sleep_forever() } pre_wait(t); - const int code = pthread_cond_wait(&t->sleep_cond, &t->sleep_mutex); - assert(code == 0 || code == ETIMEDOUT); + if (t->canceled == false) { + const int code = pthread_cond_wait(&t->sleep_cond, &t->sleep_mutex); + assert(code == 0 || code == ETIMEDOUT); + } post_wait(t); } @@ -4605,9 +4608,11 @@ rb_thread_wait_for(struct timeval time) rb_vm_thread_t *t = GET_THREAD(); pre_wait(t); - const int code = pthread_cond_timedwait(&t->sleep_cond, &t->sleep_mutex, - &ts); - assert(code == 0 || code == ETIMEDOUT); + if (t->canceled == false) { + const int code = pthread_cond_timedwait(&t->sleep_cond, &t->sleep_mutex, + &ts); + assert(code == 0 || code == ETIMEDOUT); + } post_wait(t); } @@ -4646,6 +4651,7 @@ rb_vm_thread_cancel(rb_vm_thread_t *t) pthread_assert(pthread_cond_signal(&t->sleep_cond)); } else { + t->canceled = true; pthread_assert(pthread_cancel(t->thread)); } pthread_assert(pthread_mutex_unlock(&t->sleep_mutex)); diff --git a/vm.h b/vm.h index 5df84ee..038c7a8 100644 --- a/vm.h +++ b/vm.h @@ -151,6 +151,7 @@ typedef struct rb_vm_thread { bool in_cond_wait; bool abort_on_exception; // per-local state, global one is in RoxorCore bool joined_on_exception; + bool canceled; VALUE locals; // a Hash object or Qnil VALUE exception; // killed-by exception or Qnil VALUE group; // always a ThreadGroup object }}} -- Ticket URL: <http://www.macruby.org/trac/ticket/883#comment:2> MacRuby <http://macruby.org/>