summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
authorSamuel Williams <[email protected]>2024-11-20 19:40:17 +1300
committerGitHub <[email protected]>2024-11-20 19:40:17 +1300
commit9c268302bfb4890d3757caa60981802a88bfbd89 (patch)
tree7aab2128ac5caf11baddee06d7b357dc6ab5c43d /thread.c
parent86b1c838573b5459e9e5b8fab62ec3430d2ac872 (diff)
Introduce `Fiber::Scheduler#blocking_operation_wait`. (#12016)
Redirect `rb_nogvl` blocking operations to the fiber scheduler if possible to prevent stalling the event loop. [Feature #20876]
Notes
Notes: Merged-By: ioquatix <[email protected]>
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/thread.c b/thread.c
index 64ada750b6..86c7392e9c 100644
--- a/thread.c
+++ b/thread.c
@@ -1539,6 +1539,20 @@ rb_nogvl(void *(*func)(void *), void *data1,
rb_unblock_function_t *ubf, void *data2,
int flags)
{
+ if (flags & RB_NOGVL_OFFLOAD_SAFE) {
+ VALUE scheduler = rb_fiber_scheduler_current();
+ if (scheduler != Qnil) {
+ struct rb_fiber_scheduler_blocking_operation_state state;
+
+ VALUE result = rb_fiber_scheduler_blocking_operation_wait(scheduler, func, data1, ubf, data2, flags, &state);
+
+ if (!UNDEF_P(result)) {
+ rb_errno_set(state.saved_errno);
+ return state.result;
+ }
+ }
+ }
+
void *val = 0;
rb_execution_context_t *ec = GET_EC();
rb_thread_t *th = rb_ec_thread_ptr(ec);