@@ -102,13 +102,13 @@ def call_capi_rb_thread_wakeup
102
102
end
103
103
104
104
describe "rb_thread_call_without_gvl" do
105
- it "runs a C function with the global lock unlocked" do
105
+ it "runs a C function with the global lock unlocked and can be woken by Thread#wakeup " do
106
106
thr = Thread . new do
107
107
@t . rb_thread_call_without_gvl
108
108
end
109
109
110
110
# Wait until it's blocking...
111
- Thread . pass while thr . status and thr . status != "sleep"
111
+ Thread . pass until thr . stop?
112
112
113
113
# The thread status is set to sleep by rb_thread_call_without_gvl(),
114
114
# but the thread might not be in the blocking read(2) yet, so wait a bit.
@@ -121,6 +121,40 @@ def call_capi_rb_thread_wakeup
121
121
thr . value . should be_true
122
122
end
123
123
124
+ platform_is_not :windows do
125
+ it "runs a C function with the global lock unlocked and can be woken by a signal" do
126
+ # Ruby signal handlers run on the main thread, so we need to reverse roles here and have a thread interrupt us
127
+ thr = Thread . current
128
+ thr . should == Thread . main
129
+
130
+ going_to_block = false
131
+ interrupter = Thread . new do
132
+ # Wait until it's blocking...
133
+ Thread . pass until going_to_block and thr . stop?
134
+
135
+ # The thread status is set to sleep by rb_thread_call_without_gvl(),
136
+ # but the thread might not be in the blocking read(2) yet, so wait a bit.
137
+ sleep 0.1
138
+
139
+ # Wake it up by sending a signal
140
+ done = false
141
+ prev_handler = Signal . trap ( :HUP ) { done = true }
142
+ begin
143
+ Process . kill :HUP , Process . pid
144
+ sleep 0.001 until done
145
+ ensure
146
+ Signal . trap ( :HUP , prev_handler )
147
+ end
148
+ end
149
+
150
+ going_to_block = true
151
+ # Make sure it stopped and we got a proper value
152
+ @t . rb_thread_call_without_gvl . should be_true
153
+
154
+ interrupter . join
155
+ end
156
+ end
157
+
124
158
guard -> { platform_is :mingw and ruby_version_is "" ..."2.7" } do
125
159
it "runs a C function with the global lock unlocked and unlocks IO with the generic RUBY_UBF_IO" do
126
160
thr = Thread . new do
0 commit comments