Skip to content

Commit

Permalink
Only waitReadable if errno was EAGAINish
Browse files Browse the repository at this point in the history
This code previously assumed that all -1 return values from read
meant EAGAIN and that we should proceed to selection. If the read
result was actually equivalent to EAGAIN, this was correct. If the
read result was some other error, we still would proceed to the
selection, and in most cases the same or similar error would be
raised at that point. However at least one particular case: a
"Connection reset" event caused by the other end sending RST (due
in this case to SO_LINGER=0), the selection operation did *not*
raise any error, and appeared to be readable. As a result we went
back to the read, another "Connection reset" was triggered, we
assumed it was EAGAIN, and so on.

This commit checks the errno for exactly matching EAGAIN or
EWOULDBLOCK before performing the selection, otherwise raising an
error for the failed read.

Fixes jruby#7961
  • Loading branch information
headius committed Oct 31, 2023
1 parent a518a9a commit 18a606d
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions core/src/main/java/org/jruby/util/io/OpenFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -1295,10 +1295,12 @@ public int fillbuf(ThreadContext context) {
r = readInternal(context, this, fd, rbuf.ptr, 0, rbuf.capa);

if (r < 0) {
if (waitReadable(context, fd)) {
Errno errno = posix.getErrno();
if (errno == Errno.EAGAIN || errno == Errno.EWOULDBLOCK
&& waitReadable(context, fd)) {
continue retry;
}
throw context.runtime.newErrnoFromErrno(posix.getErrno(), "channel: " + fd + (pathv != null ? " " + pathv : ""));
throw context.runtime.newErrnoFromErrno(errno, "channel: " + fd + (pathv != null ? " " + pathv : ""));
}
break;
}
Expand Down

0 comments on commit 18a606d

Please sign in to comment.