diff options
author | Samuel Williams <[email protected]> | 2020-09-06 14:48:52 +1200 |
---|---|---|
committer | Samuel Williams <[email protected]> | 2020-09-14 16:44:09 +1200 |
commit | 1a0cfe28390ce5d46f7b854eaad2b9b979c160de (patch) | |
tree | 63f5fd6d8cf9de64365039638ecd49e894858926 /thread_sync.c | |
parent | 3dc0fc11f0e21087c96781cce2360f5f6a26c7c6 (diff) |
Improve handling of urgent notification pipe.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/3434
Diffstat (limited to 'thread_sync.c')
-rw-r--r-- | thread_sync.c | 86 |
1 files changed, 41 insertions, 45 deletions
diff --git a/thread_sync.c b/thread_sync.c index cfdd62635a..9dd3b32645 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -264,12 +264,12 @@ do_mutex_lock(VALUE self, int interruptible_p) .fiber = fiber }; - if (mutex->fiber == fiber) { - rb_raise(rb_eThreadError, "deadlock; recursive locking"); - } + if (mutex->fiber == fiber) { + rb_raise(rb_eThreadError, "deadlock; recursive locking"); + } - VALUE scheduler = rb_thread_current_scheduler(); - while (mutex->fiber != fiber) { + while (mutex->fiber != fiber) { + VALUE scheduler = rb_thread_current_scheduler(); if (scheduler != Qnil) { list_add_tail(&mutex->waitq, &w.node); @@ -279,52 +279,48 @@ do_mutex_lock(VALUE self, int interruptible_p) if (!mutex->fiber) { mutex->fiber = fiber; - break; - } else { - // Try again... - continue; } - } - - enum rb_thread_status prev_status = th->status; - rb_hrtime_t *timeout = 0; - rb_hrtime_t rel = rb_msec2hrtime(100); - - th->status = THREAD_STOPPED_FOREVER; - th->locking_mutex = self; - rb_ractor_sleeper_threads_inc(th->ractor); - /* - * Carefully! while some contended threads are in native_sleep(), - * ractor->sleeper is unstable value. we have to avoid both deadlock - * and busy loop. - */ - if ((rb_ractor_living_thread_num(th->ractor) == rb_ractor_sleeper_thread_num(th->ractor)) && - !patrol_thread) { - timeout = &rel; - patrol_thread = th; - } + } else { + enum rb_thread_status prev_status = th->status; + rb_hrtime_t *timeout = 0; + rb_hrtime_t rel = rb_msec2hrtime(100); + + th->status = THREAD_STOPPED_FOREVER; + th->locking_mutex = self; + rb_ractor_sleeper_threads_inc(th->ractor); + /* + * Carefully! while some contended threads are in native_sleep(), + * ractor->sleeper is unstable value. we have to avoid both deadlock + * and busy loop. + */ + if ((rb_ractor_living_thread_num(th->ractor) == rb_ractor_sleeper_thread_num(th->ractor)) && + !patrol_thread) { + timeout = &rel; + patrol_thread = th; + } - list_add_tail(&mutex->waitq, &w.node); + list_add_tail(&mutex->waitq, &w.node); - native_sleep(th, timeout); /* release GVL */ + native_sleep(th, timeout); /* release GVL */ - list_del(&w.node); + list_del(&w.node); - if (!mutex->fiber) { - mutex->fiber = fiber; - } + if (!mutex->fiber) { + mutex->fiber = fiber; + } - if (patrol_thread == th) - patrol_thread = NULL; + if (patrol_thread == th) + patrol_thread = NULL; - th->locking_mutex = Qfalse; - if (mutex->fiber && timeout && !RUBY_VM_INTERRUPTED(th->ec)) { - rb_check_deadlock(th->ractor); - } - if (th->status == THREAD_STOPPED_FOREVER) { - th->status = prev_status; - } - rb_ractor_sleeper_threads_dec(th->ractor); + th->locking_mutex = Qfalse; + if (mutex->fiber && timeout && !RUBY_VM_INTERRUPTED(th->ec)) { + rb_check_deadlock(th->ractor); + } + if (th->status == THREAD_STOPPED_FOREVER) { + th->status = prev_status; + } + rb_ractor_sleeper_threads_dec(th->ractor); + } if (interruptible_p) { /* release mutex before checking for interrupts...as interrupt checking @@ -335,7 +331,7 @@ do_mutex_lock(VALUE self, int interruptible_p) mutex->fiber = fiber; } } - } + } if (mutex->fiber == fiber) mutex_locked(th, self); } |