summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNARUSE, Yui <nurse@users.noreply.github.com>2024-03-20 20:05:21 +0900
committerGitHub <noreply@github.com>2024-03-20 11:05:21 +0000
commit0793cbbfde261f4fc9bf7045594d62a21e391811 (patch)
tree619ca8d7c739f8ef46dd52e6c7b7f50a8a132a10
parent23bfe6218a690bbde5143e26bc6fb243347fb4b3 (diff)
merge revision(s) ef276858d9295208add48e27208c69184dc50472: [Backport #20197] (#10296)
Trigger postponed jobs on running_ec if that is available Currently, any postponed job triggered from a non-ruby thread gets sent to the main thread, but if the main thread is sleeping it won't be checking ints. Instead, we should try and interrupt running_ec if that's possible, and only fall back to the main thread if it's not. [Bug #20197] --- ractor.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
-rw-r--r--ractor.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/ractor.c b/ractor.c
index f07dd7c8e5..5bf84c7c83 100644
--- a/ractor.c
+++ b/ractor.c
@@ -2481,6 +2481,22 @@ rb_ractor_terminate_all(void)
rb_execution_context_t *
rb_vm_main_ractor_ec(rb_vm_t *vm)
{
+ /* This code needs to carefully work around two bugs:
+ * - Bug #20016: When M:N threading is enabled, running_ec is NULL if no thread is
+ * actually currently running (as opposed to without M:N threading, when
+ * running_ec will still point to the _last_ thread which ran)
+ * - Bug #20197: If the main thread is sleeping, setting its postponed job
+ * interrupt flag is pointless; it won't look at the flag until it stops sleeping
+ * for some reason. It would be better to set the flag on the running ec, which
+ * will presumably look at it soon.
+ *
+ * Solution: use running_ec if it's set, otherwise fall back to the main thread ec.
+ * This is still susceptible to some rare race conditions (what if the last thread
+ * to run just entered a long-running sleep?), but seems like the best balance of
+ * robustness and complexity.
+ */
+ rb_execution_context_t *running_ec = vm->ractor.main_ractor->threads.running_ec;
+ if (running_ec) { return running_ec; }
return vm->ractor.main_thread->ec;
}