-
-
Notifications
You must be signed in to change notification settings - Fork 942
Description
If I have a thread blocking on IO.select when my tests (running in RSpec) shut down, IO.select raises java.nio.channels.CancelledKeyException and the stack trace below is printed to the console.
I haven't been able to force this to happen when pressing ctrl-C on a running process, and it doesn't happen every time, but often.
I've observed it in JRuby 1.7.10 and 1.7.11.
From looking at the code (https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/util/io/SelectBlob.java#L340) it seems like there are two possibilities on how to end up on line 340, either key.interestOps() or key.readyOps() on line 320 throw CancelledKeyException (I don't see any other calls in the block that can throw the exception) -- but if SelectionKey works the way I think both would throw or neither would throw. Then the first thing that the catch block does is call key.interestOps(), so the answer to the comment above that line is "no" 😄
There's another odd thing in the catch block: errorResults is set only if it is not null, which means that the search that is done a few lines below that could throw an NPE. I think it might be a copy-paste error and should have been == instead of !=. However, because of the problem above I don't think this code is reachable. Could be worth fixing while this bug is fixed, though.
Exception in thread "Ruby-0-Thread-18: /path/to/gems/ione-1.0.0/lib/ione/io/io_reactor.rb:125" java.nio.channels.CancelledKeyException
at sun.nio.ch.SelectionKeyImpl.ensureValid(SelectionKeyImpl.java:73)
at sun.nio.ch.SelectionKeyImpl.interestOps(SelectionKeyImpl.java:77)
at org.jruby.util.io.SelectBlob.processSelectedKeys(SelectBlob.java:340)
at org.jruby.util.io.SelectBlob.goForIt(SelectBlob.java:90)
at org.jruby.RubyIO.select_static(RubyIO.java:3677)
at org.jruby.RubyIO.select(RubyIO.java:3673)
at org.jruby.RubyIO$INVOKER$s$0$3$select.call(RubyIO$INVOKER$s$0$3$select.gen)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:70)
at rubyjit.Ione::Io::IoLoopBody$$check_sockets!_d11515667503f3afdc971c3d423944f53ce3fe591539547357.__file__(/path/to/gems/ione-1.0.0/lib/ione/io/io_reactor.rb:307)
at rubyjit.Ione::Io::IoLoopBody$$check_sockets!_d11515667503f3afdc971c3d423944f53ce3fe591539547357.__file__(/path/to/gems/ione-1.0.0/lib/ione/io/io_reactor.rb)
at org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:181)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
at rubyjit.Ione::Io::IoLoopBody$$tick_275631e3d5785037b81518b0f3ad2a325dff51f01539547357.__file__(/path/to/gems/ione-1.0.0/lib/ione/io/io_reactor.rb:288)
at rubyjit.Ione::Io::IoLoopBody$$tick_275631e3d5785037b81518b0f3ad2a325dff51f01539547357.__file__(/path/to/gems/ione-1.0.0/lib/ione/io/io_reactor.rb)
at org.jruby.ast.executable.AbstractScript.__file__(AbstractScript.java:38)
at org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:141)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:134)
at org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:60)
at org.jruby.ast.UntilNode.interpret(UntilNode.java:120)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
at org.jruby.ast.EnsureNode.interpret(EnsureNode.java:96)
at org.jruby.ast.BeginNode.interpret(BeginNode.java:83)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
at org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
at org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
at org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:206)
at org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:194)
at org.jruby.runtime.Interpreted19Block.call(Interpreted19Block.java:125)
at org.jruby.runtime.Block.call(Block.java:101)
at org.jruby.RubyProc.call(RubyProc.java:290)
at org.jruby.RubyProc.call(RubyProc.java:228)
at org.jruby.internal.runtime.RubyRunnable.run(RubyRunnable.java:99)
at java.lang.Thread.run(Thread.java:744)