IO.select raises CancelledKeyException on shutdown #1580
If I have a thread blocking on
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
There's another odd thing in the
The text was updated successfully, but these errors were encountered:
Here's a test case, of sorts, that stresses
queue = java.util.concurrent.ConcurrentLinkedQueue.new t = Thread.start do begin while true begin r, w = IO.pipe queue.add([r, w]) IO.select([r], nil, [r], 0.1) rescue Errno::EBADF end end rescue java.nio.channels.CancelledKeyException puts "THIS SHOULD NOT HAPPEN" end end while t.alive? pair = queue.poll if pair r, w = pair w.syswrite('x') r.to_java.channel.close end end puts 'FAIL!'
I'm looking at the code and am trying to figure out what it is supposed to do when a CKE is thrown, I'm not sure if there's any cleanup that absolutely must be done. The easiest thing would be to raise a
When a CancelledKeyException is raised in IO.select/SelectBlob#processSelectedKeys it caught, but the catch block causes another one to be raised immediately. This patch removes the catch block completely (because it's never run, so nothing can rely on what it does) and raises an Errno::EBADF from SelectBlob#goForIt. CancelledKeyException is raised when the underlying channel has closed, which is normally handled. There is however a race condition in the channel selection that means that you can get a cancelled key from select if the channel is closed just after the selector determines that it is ready to read or write. It's unclear what the correct way of handling this really is, but raising EBADF feels reasonable, the channel has been closed and so it's no longer a valid file descriptor. This closes jruby#1580