Skip to content

Commit

Permalink
If select returns false, try again
Browse files Browse the repository at this point in the history
We poll after each failed select to make sure we're not supposed
to wake up and die or propagate an exception. If we are supposed
to block, we should keep blocking here until interrupted or the
stream has data.

If we proceed from here to a blocking read when data is
unavailable, we may end up inside NIO code that closes the stream
upon any interrupt. Selects are interrupt, so we work harder to
stay in select logic when doing a blocking read that might be
interrupted.
  • Loading branch information
headius committed Nov 7, 2023
1 parent ae9051d commit 8722fd2
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion core/src/main/java/org/jruby/util/io/OpenFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -1571,7 +1571,11 @@ private static void selectForRead(ThreadContext context, OpenFile fptr, ChannelF
if (fd.chSelect != null
&& fd.chNative == null // MRI does not select for rb_read_internal on native descriptors
&& !fptr.nonblock) {
context.getThread().select(fd.chSelect, fptr, SelectionKey.OP_READ);

// keep selecting for read until ready, polling each time we wake up
while (!context.getThread().select(fd.chSelect, fptr, SelectionKey.OP_READ)) {
context.pollThreadEvents();
}
}
} finally {
fptr.lock();
Expand Down

0 comments on commit 8722fd2

Please sign in to comment.