aboutsummaryrefslogtreecommitdiffstats
path: root/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/thread.c b/thread.c
index f16daafb5e..60b5ce1af6 100644
--- a/thread.c
+++ b/thread.c
@@ -132,6 +132,8 @@ rb_thread_local_storage(VALUE thread)
enum SLEEP_FLAGS {
SLEEP_DEADLOCKABLE = 0x01,
SLEEP_SPURIOUS_CHECK = 0x02,
+ SLEEP_ALLOW_SPURIOUS = 0x04,
+ SLEEP_NO_CHECKINTS = 0x08,
};
static void sleep_forever(rb_thread_t *th, unsigned int fl);
@@ -418,6 +420,7 @@ rb_threadptr_join_list_wakeup(rb_thread_t *thread)
case THREAD_STOPPED:
case THREAD_STOPPED_FOREVER:
target_thread->status = THREAD_RUNNABLE;
+ break;
default:
break;
}
@@ -1053,7 +1056,7 @@ thread_join_sleep(VALUE arg)
rb_fiber_scheduler_block(scheduler, target_th->self, p->timeout);
}
else if (!limit) {
- sleep_forever(th, SLEEP_DEADLOCKABLE);
+ sleep_forever(th, SLEEP_DEADLOCKABLE | SLEEP_ALLOW_SPURIOUS | SLEEP_NO_CHECKINTS);
}
else {
if (hrtime_update_expire(limit, end)) {
@@ -1338,7 +1341,9 @@ sleep_forever(rb_thread_t *th, unsigned int fl)
status = fl & SLEEP_DEADLOCKABLE ? THREAD_STOPPED_FOREVER : THREAD_STOPPED;
th->status = status;
- RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
+
+ if (!(fl & SLEEP_NO_CHECKINTS)) RUBY_VM_CHECK_INTS_BLOCKING(th->ec);
+
while (th->status == status) {
if (fl & SLEEP_DEADLOCKABLE) {
rb_ractor_sleeper_threads_inc(th->ractor);
@@ -1350,6 +1355,9 @@ sleep_forever(rb_thread_t *th, unsigned int fl)
if (fl & SLEEP_DEADLOCKABLE) {
rb_ractor_sleeper_threads_dec(th->ractor);
}
+ if (fl & SLEEP_ALLOW_SPURIOUS) {
+ break;
+ }
woke = vm_check_ints_blocking(th->ec);