@@ -208,7 +208,10 @@ rb_fiber_scheduler_blocking_operation_execute(rb_fiber_scheduler_blocking_operat
208
208
return -1 ; // Invalid blocking operation
209
209
}
210
210
211
- // Atomically check if we can transition from QUEUED to EXECUTING
211
+ // Resolve sentinel values for unblock_function and data2:
212
+ rb_thread_resolve_unblock_function (& blocking_operation -> unblock_function , & blocking_operation -> data2 , GET_THREAD ());
213
+
214
+ // Atomically check if we can transition from QUEUED to EXECUTING
212
215
rb_atomic_t expected = RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_QUEUED ;
213
216
if (RUBY_ATOMIC_CAS (blocking_operation -> status , expected , RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_EXECUTING ) != expected ) {
214
217
// Already cancelled or in wrong state
@@ -1124,25 +1127,33 @@ rb_fiber_scheduler_blocking_operation_cancel(rb_fiber_scheduler_blocking_operati
1124
1127
1125
1128
rb_atomic_t current_state = RUBY_ATOMIC_LOAD (blocking_operation -> status );
1126
1129
1127
- switch (current_state ) {
1130
+ switch (current_state ) {
1128
1131
case RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_QUEUED :
1129
- // Work hasn't started - just mark as cancelled
1132
+ // Work hasn't started - just mark as cancelled:
1130
1133
if (RUBY_ATOMIC_CAS (blocking_operation -> status , current_state , RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_CANCELLED ) == current_state ) {
1131
- return 0 ; // Successfully cancelled before execution
1134
+ // Successfully cancelled before execution:
1135
+ return 0 ;
1132
1136
}
1133
1137
// Fall through if state changed between load and CAS
1134
1138
1135
1139
case RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_EXECUTING :
1136
1140
// Work is running - mark cancelled AND call unblock function
1137
- RUBY_ATOMIC_SET (blocking_operation -> status , RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_CANCELLED );
1138
- if (blocking_operation -> unblock_function ) {
1141
+ if (RUBY_ATOMIC_CAS (blocking_operation -> status , current_state , RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_CANCELLED ) != current_state ) {
1142
+ // State changed between load and CAS - operation may have completed:
1143
+ return 0 ;
1144
+ }
1145
+ // Otherwise, we successfully marked it as cancelled, so we can call the unblock function:
1146
+ rb_unblock_function_t * unblock_function = blocking_operation -> unblock_function ;
1147
+ if (unblock_function ) {
1148
+ RUBY_ASSERT (unblock_function != (rb_unblock_function_t * )-1 && "unblock_function is still sentinel value -1, should have been resolved earlier" );
1139
1149
blocking_operation -> unblock_function (blocking_operation -> data2 );
1140
1150
}
1141
- return 1 ; // Cancelled during execution (unblock function called)
1151
+ // Cancelled during execution (unblock function called):
1152
+ return 1 ;
1142
1153
1143
1154
case RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_COMPLETED :
1144
1155
case RB_FIBER_SCHEDULER_BLOCKING_OPERATION_STATUS_CANCELLED :
1145
- // Already finished or cancelled
1156
+ // Already finished or cancelled:
1146
1157
return 0 ;
1147
1158
}
1148
1159
0 commit comments