Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket.read(0) blocks caller (but not in MRI) #1637

Closed
unclebilly opened this Issue Apr 16, 2014 · 3 comments

Comments

Projects
None yet
4 participants
@unclebilly
Copy link

unclebilly commented Apr 16, 2014

I found a discrepancy between how JRuby (1.7.12) and MRI (1.9.3, 2.1.1) read 0 bytes from a socket. Consider this example:

require 'socket'
socket = TCPSocket.new('127.0.0.1', 80)
socket.read(0)

In JRuby 1.7.12, this code blocks the caller.
In MRI 1.9.3 and 2.1.1, this code immediately returns an empty string.

@zanker

This comment has been minimized.

Copy link

zanker commented Dec 18, 2014

We actually just ran into this bug with using RBHive on JRuby 1.7.17. RBHive was doing a read(0) as part of a SASL authentication https://github.com/forward3d/rbhive/blob/3f1737f8d84f6ac60837b0f0ab4a22521e1c48c2/lib/thrift/sasl_client_transport.rb#L73 which causes RBHive to not work when using SASL.

I'm going to fix it in RBHive, but it would be good to get it fixed in JRuby. Even if it's kind of odd that MRI returns an empty string immediately, it's a really subtle inconsistency.

@enebo enebo added this to the JRuby 1.7.19 milestone Dec 19, 2014

@enebo

This comment has been minimized.

Copy link
Member

enebo commented Dec 19, 2014

@zanker Have you had a change to try master (which will be JRuby 9000)? IO has been rewritten so it would be great to know before we put out our first preview release.

@headius

This comment has been minimized.

Copy link
Member

headius commented Dec 19, 2014

Fix is here. Up to @enebo if this goes into .18 or .19.

diff --git a/core/src/main/java/org/jruby/RubyIO.java b/core/src/main/java/org/jruby/RubyIO.java
index 57a5988..4e46528 100644
--- a/core/src/main/java/org/jruby/RubyIO.java
+++ b/core/src/main/java/org/jruby/RubyIO.java
@@ -3136,6 +3136,8 @@ public class RubyIO extends RubyObject implements IOEncodable {
         Ruby runtime = context.runtime;
         str.empty();

+        if (length == 0) return str;
+
         try {
             ByteList newBuffer = readNotAllCommon(context, myOpenFile, length);

@@ -3161,6 +3163,8 @@ public class RubyIO extends RubyObject implements IOEncodable {
     private IRubyObject readNotAll(ThreadContext context, OpenFile myOpenFile, int length) {
         Ruby runtime = context.runtime;

+        if (length == 0) return RubyString.newEmptyString(runtime);
+
         try {
             ByteList newBuffer = readNotAllCommon(context, myOpenFile, length);

headius added a commit that referenced this issue Dec 22, 2014

@headius headius closed this Dec 22, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.