@@ -1088,15 +1088,6 @@ rb_fiber_scheduler_address_resolve(VALUE scheduler, VALUE hostname)
10881088 * Thread.new { blocking_operation.call }.join
10891089 * end
10901090 */
1091- // Helper for rb_protect: calls scheduler.blocking_operation_wait(blocking_operation).
1092- // args[0] = scheduler VALUE, args[1] = blocking_operation VALUE.
1093- static VALUE
1094- scheduler_blocking_operation_wait_call (VALUE _args )
1095- {
1096- VALUE * args = (VALUE * )_args ;
1097- return rb_funcall (args [0 ], id_blocking_operation_wait , 1 , args [1 ]);
1098- }
1099-
11001091VALUE rb_fiber_scheduler_blocking_operation_wait (VALUE scheduler , void * (* function )(void * ), void * data , rb_unblock_function_t * unblock_function , void * data2 , int flags , struct rb_fiber_scheduler_blocking_operation_state * state )
11011092{
11021093 // Check if scheduler supports blocking_operation_wait before creating the object
@@ -1107,35 +1098,22 @@ VALUE rb_fiber_scheduler_blocking_operation_wait(VALUE scheduler, void* (*functi
11071098 // Create a new BlockingOperation with the blocking operation
11081099 VALUE blocking_operation = rb_fiber_scheduler_blocking_operation_new (function , data , unblock_function , data2 , flags , state );
11091100
1110- rb_fiber_scheduler_blocking_operation_t * operation = get_blocking_operation (blocking_operation );
1111-
1112- // Use rb_protect so that cleanup runs even when the scheduler raises an exception
1113- // (e.g. via rb_jump_tag from worker_pool_call). Without this, a longjmp from
1114- // inside rb_funcall bypasses the cleanup below and RB_GC_GUARD, leaving
1115- // operation with stale pointers and blocking_operation without a live GC root.
1116- VALUE call_args [2 ] = {scheduler , blocking_operation };
1117- int tag = 0 ;
1118- VALUE result = rb_protect (scheduler_blocking_operation_wait_call , (VALUE )call_args , & tag );
1119-
1120- operation = get_blocking_operation (blocking_operation );
1101+ VALUE result = rb_funcall (scheduler , id_blocking_operation_wait , 1 , blocking_operation );
11211102
11221103 // Get the operation data to check if it was executed
1104+ rb_fiber_scheduler_blocking_operation_t * operation = get_blocking_operation (blocking_operation );
11231105 rb_atomic_t current_status = RUBY_ATOMIC_LOAD (operation -> status );
11241106
1125- // Invalidate the operation now that we're done with it — must happen even on
1126- // exception paths, since operation->state may point to a caller's stack frame.
1107+ // Invalidate the operation now that we're done with it
11271108 operation -> function = NULL ;
11281109 operation -> state = NULL ;
11291110 operation -> data = NULL ;
11301111 operation -> data2 = NULL ;
11311112 operation -> unblock_function = NULL ;
11321113
1133- // Ensure that blocking_operation remains a live GC root through the cleanup above.
1114+ // Ensure that the blocking operation remains visible until this point:
11341115 RB_GC_GUARD (blocking_operation );
11351116
1136- // Re-raise any exception from the scheduler after cleanup.
1137- if (tag ) rb_jump_tag (tag );
1138-
11391117 // If the blocking operation was never executed, return Qundef to signal the caller to use rb_nogvl instead
11401118 if (current_status == RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_QUEUED ) {
11411119 return Qundef ;
0 commit comments