Skip to content

IO.select raises CancelledKeyException on shutdown #1580

@iconara

Description

@iconara

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions