1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
Koichi Sasada 2020-12-17 00:31:14 +09:00
parent 84c9ebd65f
commit 24f018972b

View file

@ -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