diff options
author | Koichi Sasada <ko1@atdot.net> | 2020-12-17 00:31:14 +0900 |
---|---|---|
committer | Koichi Sasada <ko1@atdot.net> | 2020-12-17 00:34:30 +0900 |
commit | 24f018972b958d6287c71a4682ea1dcc8d1fa16e (patch) | |
tree | 0066a2eb5f868fc9a0044eaaa238a86f7d3625cf /ractor.c | |
parent | 84c9ebd65f8a6fcd2e22225c563fb671dc690a9a (diff) |
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
Diffstat (limited to 'ractor.c')
-rw-r--r-- | ractor.c | 28 |
1 files changed, 21 insertions, 7 deletions
@@ -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 |