summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-12-17 00:31:14 +0900
committerKoichi Sasada <ko1@atdot.net>2020-12-17 00:34:30 +0900
commit24f018972b958d6287c71a4682ea1dcc8d1fa16e (patch)
tree0066a2eb5f868fc9a0044eaaa238a86f7d3625cf
parent84c9ebd65f8a6fcd2e22225c563fb671dc690a9a (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
-rw-r--r--ractor.c28
1 files 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