diff --git a/thread.c b/thread.c index 342d4fe..86df518 100644 --- a/thread.c +++ b/thread.c @@ -563,6 +563,8 @@ thread_create_core(VALUE thval, VALUE args, VALUE (*fn)(ANYARGS)) th->priority = GET_THREAD()->priority; th->thgroup = GET_THREAD()->thgroup; + th->spinlock_waiting_gvl = 0; + native_mutex_initialize(&th->interrupt_lock); if (GET_VM()->event_hooks != NULL) th->event_flags |= RUBY_EVENT_VM; @@ -3573,9 +3575,11 @@ rb_mutex_lock(VALUE self) } GVL_UNLOCK_BEGIN(); interrupted = lock_func(th, mutex, timeout_ms); + th->spinlock_waiting_gvl = 1; native_mutex_unlock(&mutex->lock); GVL_UNLOCK_END(); + th->spinlock_waiting_gvl = 0; reset_unblock_function(th, &oldubf); th->locking_mutex = Qfalse; @@ -4740,7 +4744,7 @@ check_deadlock_i(st_data_t key, st_data_t val, int *found) GetMutexPtr(th->locking_mutex, mutex); native_mutex_lock(&mutex->lock); - if (mutex->th == th || (!mutex->th && mutex->cond_waiting)) { + if (mutex->th == th || (!mutex->th && (mutex->cond_waiting || th->spinlock_waiting_gvl))) { *found = 1; } native_mutex_unlock(&mutex->lock); diff --git a/vm_core.h b/vm_core.h index 7211005..849482d 100644 --- a/vm_core.h +++ b/vm_core.h @@ -440,6 +440,7 @@ typedef struct rb_thread_struct { rb_thread_lock_t interrupt_lock; struct rb_unblock_callback unblock; VALUE locking_mutex; + int spinlock_waiting_gvl; struct rb_mutex_struct *keeping_mutexes; struct rb_vm_tag *tag;