From 24f018972b958d6287c71a4682ea1dcc8d1fa16e Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Thu, 17 Dec 2020 00:31:14 +0900 Subject: fix timing bug ractor_sleep() can remain wait.status by interrupt, so that this patch handles more correctly. This patch fixed this kind of assertion failures: Assertion Failed: ../src/ractor.c:1332:ractor_yield_atexit:cr->sync.wait.status == wait_none --- ractor.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/ractor.c b/ractor.c index d0f5185225..0817a1b5c8 100644 --- a/ractor.c +++ b/ractor.c @@ -503,11 +503,13 @@ ractor_sleep_wo_gvl(void *ptr) { rb_ractor_t *cr = ptr; RACTOR_LOCK_SELF(cr); - VM_ASSERT(cr->sync.wait.status != wait_none); - if (cr->sync.wait.wakeup_status == wakeup_none) { - ractor_cond_wait(cr); + { + VM_ASSERT(cr->sync.wait.status != wait_none); + if (cr->sync.wait.wakeup_status == wakeup_none) { + ractor_cond_wait(cr); + } + cr->sync.wait.status = wait_none; } - cr->sync.wait.status = wait_none; RACTOR_UNLOCK_SELF(cr); return NULL; } @@ -567,10 +569,22 @@ ractor_sleep(rb_execution_context_t *ec, rb_ractor_t *cr) // wait_status_str(cr->sync.wait.status), wakeup_status_str(cr->sync.wait.wakeup_status)); RACTOR_UNLOCK(cr); - rb_nogvl(ractor_sleep_wo_gvl, cr, - ractor_sleep_interrupt, cr, - RB_NOGVL_UBF_ASYNC_SAFE); + { + rb_nogvl(ractor_sleep_wo_gvl, cr, + ractor_sleep_interrupt, cr, + RB_NOGVL_UBF_ASYNC_SAFE | RB_NOGVL_INTR_FAIL); + } RACTOR_LOCK(cr); + + // rb_nogvl() can be canceled by interrupts + if (cr->sync.wait.status != wait_none) { + cr->sync.wait.status = wait_none; + cr->sync.wait.wakeup_status = wakeup_by_interrupt; + + RACTOR_UNLOCK(cr); + rb_thread_check_ints(); + RACTOR_LOCK(cr); // reachable? + } } static bool -- cgit v1.2.3