Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Thread#value should return nil when its thread was waited by Mutex#lo…

…ck and was killed.
  • Loading branch information...
commit be9df8e45280db059d97a5bb17f3a89f99405299 1 parent 95a47d3
@Watson1978 Watson1978 authored
Showing with 17 additions and 5 deletions.
  1. +0 −2  test-mri/test/ruby/test_thread.rb
  2. +14 −2 thread.c
  3. +2 −1  vm.cpp
  4. +1 −0  vm.h
View
2  test-mri/test/ruby/test_thread.rb
@@ -521,8 +521,6 @@ def test_mutex_deadlock
end
def test_mutex_interrupt
- skip("[BUG : #???] Timeout, MacRuby don't finish")
-
m = Mutex.new
m.lock
t = Thread.new do
View
16 thread.c
@@ -195,6 +195,9 @@ thread_join_m(VALUE self, SEL sel, int argc, VALUE *argv)
while (t->status != THREAD_DEAD) {
nanosleep(&ts, NULL);
pthread_yield_np();
+ if (t->status == THREAD_KILLED && t->wait_for_mutex_lock) {
+ goto dead;
+ }
}
}
else {
@@ -229,6 +232,9 @@ thread_join_m(VALUE self, SEL sel, int argc, VALUE *argv)
if (t->status == THREAD_DEAD) {
goto dead;
}
+ if (t->status == THREAD_KILLED && t->wait_for_mutex_lock) {
+ goto dead;
+ }
}
return Qnil;
}
@@ -1458,13 +1464,19 @@ rb_mutex_lock(VALUE self, SEL sel)
{
rb_vm_thread_t *current = GetThreadPtr(rb_vm_current_thread());
rb_vm_mutex_t *m = GetMutexPtr(self);
+ rb_vm_thread_status_t prev_status;
if (m->thread == current) {
rb_raise(rb_eThreadError, "deadlock; recursive locking");
}
- current->status = THREAD_SLEEP;
+ prev_status = current->status;
+ if (current->status == THREAD_ALIVE) {
+ current->status = THREAD_SLEEP;
+ }
+ current->wait_for_mutex_lock = true;
pthread_assert(pthread_mutex_lock(&m->mutex));
- current->status = THREAD_ALIVE;
+ current->wait_for_mutex_lock = false;
+ current->status = prev_status;
m->thread = current;
if (current->mutexes == Qnil) {
GC_WB(&current->mutexes, rb_ary_new());
View
3  vm.cpp
@@ -4982,13 +4982,14 @@ rb_vm_thread_pre_init(rb_vm_thread_t *t, rb_vm_block_t *body, int argc,
}
t->vm = vm;
- t->value = Qundef;
+ t->value = Qnil;
t->locals = Qnil;
t->exception = Qnil;
t->status = THREAD_ALIVE;
t->in_cond_wait = false;
t->abort_on_exception = false;
t->joined_on_exception = false;
+ t->wait_for_mutex_lock = false;
t->group = Qnil; // will be set right after
t->mutexes = Qnil;
View
1  vm.h
@@ -180,6 +180,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 wait_for_mutex_lock;
VALUE locals; // a Hash object or Qnil
VALUE exception; // killed-by exception or Qnil
VALUE group; // always a ThreadGroup object
Please sign in to comment.
Something went wrong with that request. Please try again.