[ruby-core:126350] [Ruby Bug#15499] Breaking behavior on ruby 2.6: rb_thread_call_without_gvl doesn't invoke unblock_function when used on the main thread
Issue #15499 has been updated by wanabe (_ wanabe). It looks like it might be fixed with 1d4822a175a0dfccca8f252b0e757a1991bd54f9, but I'm not sure. ``` $ git checkout 1d4822a175a0dfccca8f252b0e757a1991bd54f9~; if make -j miniruby >/dev/null 2>&1; then ./miniruby -e 'Thread.new { Ractor.receive }; Ractor.receive' & CH=$! && sleep 1 && kill -INT $CH && sleep 1 && ps aux|grep "^[^ ]* *$CH" && kill -KILL $CH; fi HEAD is now at 2fee379f8f0 Checkout .github on omnibus result for notifications [1] 797951 wanabe 797951 0.0 0.0 526288 9920 pts/7 Sl 20:38 0:00 ./miniruby -e Thread.new{ Ractor.receive }; Ractor.receive [1]+ Killed ./miniruby -e 'Thread.new{ Ractor.receive }; Ractor.receive' $ git checkout 1d4822a175a0dfccca8f252b0e757a1991bd54f9; if make -j miniruby >/dev/null 2>&1; then ./miniruby -e 'Thread.new{ Ractor.receive }; Ractor.receive' & CH=$! && sleep 1 && kill -INT $CH && sleep 1 && ps aux|grep "^[^ ]* *$CH" && kill -KILL $CH; fi Previous HEAD position was 2fee379f8f0 Checkout .github on omnibus result for notifications HEAD is now at 1d4822a175a Get ractor message passing working with > 1 thread sending/receiving values in same ractor [1] 798878 <internal:ractor>:431:in 'Ractor.receive': Interrupt from -e:1:in '<main>' [1]+ Interrupt ./miniruby -e 'Thread.new{ Ractor.receive }; Ractor.receive' ``` ---------------------------------------- Bug #15499: Breaking behavior on ruby 2.6: rb_thread_call_without_gvl doesn't invoke unblock_function when used on the main thread https://bugs.ruby-lang.org/issues/15499#change-118474 * Author: apolcyn (alex polcyn) * Status: Assigned * Assignee: ko1 (Koichi Sasada) * ruby -v: master * Backport: 2.4: DONTNEED, 2.5: DONTNEED, 2.6: DONE ---------------------------------------- This issue was noticed when trying to add ruby 2.6 support to the "grpc" ruby gem (this gem is a native C-extension), and was caught by a unit test. There are several APIs on the grpc ruby gem (https://github.com/grpc/grpc/tree/master/src/ruby) that invoke "rb_thread_call_without_gvl" on the current thread, doing a blocking operation in the "without gvl" callback and cancel that blocking operation in the "unblocking function". These APIs work in ruby versions prior to ruby 2.6 (e.g. ruby 2.5), but have problems when used on ruby 2.6 Minimal repro: My system: ```
lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 9.6 (stretch) Release: 9.6 Codename: stretch
ruby -v ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-linux
# I installed ruby 2.6.0 with rvm - https://rvm.io/rvm/install
GRPC_CONFIG=dbg gem install grpc --platform ruby # build grpc gem from source with debug symbols
ruby script, "repro.rb" that looks like this:
```ruby
require 'grpc'
ch = GRPC::Core::Channel.new('localhost:1234', {}, :this_channel_is_insecure)
ch.watch_connectivity_state(ch.connectivity_state, Time.now + 360)
Run "ruby repro.rb" with an interactive shell, and it will hang there. At this point, ctrl^C the process, and it will not terminate. What should happen is this unblocking func should be invoked: https://github.com/grpc/grpc/blob/master/src/ruby/ext/grpc/rb_channel.c#L354, but as seen with logging or debuggers, that unblocking func is never ran. Thus the blocking operation never completes and the main thread is stuck. When the same repro.rb is ran on e.g. ruby 2.5.3 or ruby 2.4.1, the blocking operation is unblocked and the process terminates, as expected, when sending it a SIGINT. Also note that if the blocking operation is put in a background thread, e.g. with this script: ```ruby require 'grpc' th = Thread.new do ch = GRPC::Core::Channel.new('localhost:1234', {}, :this_channel_is_insecure) ch.watch_connectivity_state(ch.connectivity_state, Time.now + 360) end th.join ``` then "unblocking" functions will in fact be invoked upon sending the process a SIGINT, so this looks like a problem specifically with rb_thread_call_without_gvl being used on the main thread. Please let me know and I can provide more details or alternative repro cases. Thanks in advance. -- https://bugs.ruby-lang.org/
participants (1)
-
wanabe (_ wanabe)