Skip to content

Commit

Permalink
Default to nonblocking whenever possible
Browse files Browse the repository at this point in the history
Ruby 3.0 began to set O_NONBLOCK by default for all IO, to allow more IO
types to enlist in the new IO/fiber scheduling. JRuby has not previously
defaulted to nonblock, but all IO operations against nonblock-compatible
channels does use nonblocking semantics, so all we really need to align
with CRuby is to just set them non-blocking at the NIO level on
creation.

We can only do this when the underlying channel supports
nonblocking semantics, but this commit attempts to set such
channels up properly.

Part of scheduler work in #7459 and related issues.
  • Loading branch information
headius committed Nov 21, 2022
1 parent f4a4c5e commit adc8055
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 0 deletions.
11 changes: 11 additions & 0 deletions core/src/main/java/org/jruby/RubyIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,15 @@ private IRubyObject initializeCommon(ThreadContext context, int fileno, IRubyObj
}
}
}

// set to nonblocking if possible (Ruby 3.0 change for IO/fiber scheduling)
if (fd.chSelect != null) {
try {
fd.chSelect.configureBlocking(false);
} catch (IOException ioe) {
// ignore, can't set nonblocking
}
}
} else {
fd = runtime.getFilenoUtil().getWrapperFromFileno(fileno);

Expand Down Expand Up @@ -4147,6 +4156,7 @@ private void setupPopen(final Ruby runtime, ModeFlags modes, POpenProcess proces
ChannelFD main = new ChannelFD(inChannel, runtime.getPosix(), runtime.getFilenoUtil());

openFile.setFD(main);
openFile.setBlocking(runtime, false);
}

if (openFile.isWritable() && process.hasOutput()) {
Expand All @@ -4169,6 +4179,7 @@ private void setupPopen(final Ruby runtime, ModeFlags modes, POpenProcess proces
setInstanceVariable("@tied_io_for_writing", writeIO);
} else {
openFile.setFD(pipe);
openFile.setBlocking(runtime, false);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,7 @@ protected void initSocket(ChannelFD fd) {
MakeOpenFile();

openFile.setFD(fd);
openFile.setBlocking(getRuntime(), false);
openFile.setMode(OpenFile.READWRITE | OpenFile.SYNC);

// see rsock_init_sock in MRI; sockets are initialized to binary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ protected void init_sock(Ruby runtime, Channel channel, String path) {
ModeFlags modes = newModeFlags(runtime, ModeFlags.RDWR);

openFile.setFD(newChannelFD(runtime, channel));
openFile.setBlocking(runtime, false);
openFile.setMode(modes.getOpenFileFlags());
openFile.setSync(true);
openFile.setPath(path);
Expand Down
8 changes: 8 additions & 0 deletions core/src/main/java/org/jruby/util/io/OpenFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,18 @@ public boolean IS_PREP_STDIO() {

public void setFD(ChannelFD fd) {
this.fd = fd;
updateBlockingFromFD(fd);
}

public void setChannel(Channel fd) {
this.fd = new ChannelFD(fd, runtime.getPosix(), runtime.getFilenoUtil());
updateBlockingFromFD(this.fd);
}

private void updateBlockingFromFD(ChannelFD fd) {
if (fd.chSelect != null ) {
this.nonblock = !fd.chSelect.isBlocking();
}
}

public int getMode() {
Expand Down

0 comments on commit adc8055

Please sign in to comment.