Bug #4723 » 0001-remove-transition_for_lock.patch
| thread.c | ||
|---|---|---|
| { | ||
|     int interrupted = 0; | ||
|     int err = 0; | ||
|     native_mutex_lock(&mutex->lock); | ||
|     th->transition_for_lock = 0; | ||
|     mutex->cond_waiting++; | ||
|     for (;;) { | ||
| ... | ... | |
| 	} | ||
|     } | ||
|     mutex->cond_waiting--; | ||
|     th->transition_for_lock = 1; | ||
|     native_mutex_unlock(&mutex->lock); | ||
|     return interrupted; | ||
| } | ||
| ... | ... | |
| 	    set_unblock_function(th, lock_interrupt, mutex, &oldubf); | ||
| 	    th->status = THREAD_STOPPED_FOREVER; | ||
| 	    th->vm->sleeper++; | ||
| 	    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 | ||
| 	     * and busy loop. | ||
| 	     */ | ||
| 	    if (vm_living_thread_num(th->vm) == th->vm->sleeper) { | ||
| 		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; | ||
| 	    remove_signal_thread_list(th); | ||
| 	    reset_unblock_function(th, &oldubf); | ||
| 	    th->locking_mutex = Qfalse; | ||
| ... | ... | |
|     rb_thread_t *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; | ||
|     } | ||
|     else if (th->locking_mutex) { | ||
| ... | ... | |
|     rb_thread_t *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) { | ||
| 	mutex_t *mutex; | ||
| 	GetMutexPtr(th->locking_mutex, mutex); | ||
| vm_core.h | ||
|---|---|---|
|     struct rb_unblock_callback unblock; | ||
|     VALUE locking_mutex; | ||
|     struct rb_mutex_struct *keeping_mutexes; | ||
|     int transition_for_lock; | ||
|     struct rb_vm_tag *tag; | ||
|     struct rb_vm_protect_tag *protect_tag; | ||