[MacRuby] #883: Abort occurs when calls Thread#kill, Using 32bit arch.

MacRuby ruby-noreply at macosforge.org
Tue Sep 7 17:21:50 PDT 2010


#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/>



More information about the macruby-tickets mailing list