* thread.c: remove th->transition_for_lock. It's thread unsafe.
[Bug #4723][ruby-dev:43563] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32022 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
614fcdf66c
commit
f0041fa0fd
@ -1,3 +1,8 @@
|
|||||||
|
Sun Jun 12 15:56:08 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
|
* thread.c: remove th->transition_for_lock. It's thread unsafe.
|
||||||
|
[Bug #4723][ruby-dev:43563]
|
||||||
|
|
||||||
Sun Jun 12 15:47:35 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
Sun Jun 12 15:47:35 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
* thread.c: introduce spurious wakeup safe deadlock check.
|
* thread.c: introduce spurious wakeup safe deadlock check.
|
||||||
|
24
thread.c
24
thread.c
@ -3459,9 +3459,6 @@ lock_func(rb_thread_t *th, mutex_t *mutex, int timeout_ms)
|
|||||||
int interrupted = 0;
|
int interrupted = 0;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
native_mutex_lock(&mutex->lock);
|
|
||||||
th->transition_for_lock = 0;
|
|
||||||
|
|
||||||
mutex->cond_waiting++;
|
mutex->cond_waiting++;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!mutex->th) {
|
if (!mutex->th) {
|
||||||
@ -3493,9 +3490,6 @@ lock_func(rb_thread_t *th, mutex_t *mutex, int timeout_ms)
|
|||||||
}
|
}
|
||||||
mutex->cond_waiting--;
|
mutex->cond_waiting--;
|
||||||
|
|
||||||
th->transition_for_lock = 1;
|
|
||||||
native_mutex_unlock(&mutex->lock);
|
|
||||||
|
|
||||||
return interrupted;
|
return interrupted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3537,23 +3531,23 @@ rb_mutex_lock(VALUE self)
|
|||||||
|
|
||||||
set_unblock_function(th, lock_interrupt, mutex, &oldubf);
|
set_unblock_function(th, lock_interrupt, mutex, &oldubf);
|
||||||
th->status = THREAD_STOPPED_FOREVER;
|
th->status = THREAD_STOPPED_FOREVER;
|
||||||
th->vm->sleeper++;
|
|
||||||
th->locking_mutex = self;
|
th->locking_mutex = self;
|
||||||
|
|
||||||
|
native_mutex_lock(&mutex->lock);
|
||||||
|
th->vm->sleeper++;
|
||||||
/*
|
/*
|
||||||
* Carefully! while some contended threads are in lock_fun(),
|
* Carefully! while some contended threads are in lock_func(),
|
||||||
* vm->sleepr is unstable value. we have to avoid both deadlock
|
* vm->sleepr is unstable value. we have to avoid both deadlock
|
||||||
* and busy loop.
|
* and busy loop.
|
||||||
*/
|
*/
|
||||||
if (vm_living_thread_num(th->vm) == th->vm->sleeper) {
|
if (vm_living_thread_num(th->vm) == th->vm->sleeper) {
|
||||||
timeout_ms = 100;
|
timeout_ms = 100;
|
||||||
}
|
}
|
||||||
|
GVL_UNLOCK_BEGIN();
|
||||||
|
interrupted = lock_func(th, mutex, timeout_ms);
|
||||||
|
native_mutex_unlock(&mutex->lock);
|
||||||
|
GVL_UNLOCK_END();
|
||||||
|
|
||||||
th->transition_for_lock = 1;
|
|
||||||
BLOCKING_REGION_CORE({
|
|
||||||
interrupted = lock_func(th, mutex, timeout_ms);
|
|
||||||
});
|
|
||||||
th->transition_for_lock = 0;
|
|
||||||
reset_unblock_function(th, &oldubf);
|
reset_unblock_function(th, &oldubf);
|
||||||
|
|
||||||
th->locking_mutex = Qfalse;
|
th->locking_mutex = Qfalse;
|
||||||
@ -4728,7 +4722,7 @@ check_deadlock_i(st_data_t key, st_data_t val, int *found)
|
|||||||
rb_thread_t *th;
|
rb_thread_t *th;
|
||||||
GetThreadPtr(thval, th);
|
GetThreadPtr(thval, th);
|
||||||
|
|
||||||
if (th->status != THREAD_STOPPED_FOREVER || RUBY_VM_INTERRUPTED(th) || th->transition_for_lock) {
|
if (th->status != THREAD_STOPPED_FOREVER || RUBY_VM_INTERRUPTED(th)) {
|
||||||
*found = 1;
|
*found = 1;
|
||||||
}
|
}
|
||||||
else if (th->locking_mutex) {
|
else if (th->locking_mutex) {
|
||||||
@ -4753,7 +4747,7 @@ debug_i(st_data_t key, st_data_t val, int *found)
|
|||||||
rb_thread_t *th;
|
rb_thread_t *th;
|
||||||
GetThreadPtr(thval, th);
|
GetThreadPtr(thval, th);
|
||||||
|
|
||||||
printf("th:%p %d %d %d", th, th->status, th->interrupt_flag, th->transition_for_lock);
|
printf("th:%p %d %d", th, th->status, th->interrupt_flag);
|
||||||
if (th->locking_mutex) {
|
if (th->locking_mutex) {
|
||||||
mutex_t *mutex;
|
mutex_t *mutex;
|
||||||
GetMutexPtr(th->locking_mutex, mutex);
|
GetMutexPtr(th->locking_mutex, mutex);
|
||||||
|
@ -436,7 +436,6 @@ typedef struct rb_thread_struct {
|
|||||||
struct rb_unblock_callback unblock;
|
struct rb_unblock_callback unblock;
|
||||||
VALUE locking_mutex;
|
VALUE locking_mutex;
|
||||||
struct rb_mutex_struct *keeping_mutexes;
|
struct rb_mutex_struct *keeping_mutexes;
|
||||||
volatile int transition_for_lock;
|
|
||||||
|
|
||||||
struct rb_vm_tag *tag;
|
struct rb_vm_tag *tag;
|
||||||
struct rb_vm_protect_tag *protect_tag;
|
struct rb_vm_protect_tag *protect_tag;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user