Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3acdc1d50548
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ae515966b9cb
Choose a head ref
  • 7 commits
  • 6 files changed
  • 1 contributor

Commits on Jun 16, 2016

  1. Verified

    This commit was signed with the committer’s verified signature.
    makenowjust Hiroya Fujinami
    Copy the full SHA
    4c3a88b View commit details
  2. Copy the full SHA
    2ef0858 View commit details
  3. fix Socket's #recv_nonblock and UDPSocket#recvfrom_nonblock

    returning :wait_readable instead of raising when op would block
    kares committed Jun 16, 2016
    Copy the full SHA
    239e1de View commit details
  4. Copy the full SHA
    388030b View commit details
  5. Copy the full SHA
    3a1a9e4 View commit details
  6. avoid copy-ing byte[] from buffer to byte-list

    + hide method (receiving a buffer param) used internaly
    kares committed Jun 16, 2016
    Copy the full SHA
    5ddb20a View commit details
  7. Copy the full SHA
    ae51596 View commit details
8 changes: 4 additions & 4 deletions core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
@@ -1004,10 +1004,10 @@ public final void view(ByteList bytes) {
shareLevel = SHARE_LEVEL_NONE;
}

private void view(byte[]bytes) {
private void view(byte[] bytes, boolean copy) {
modifyCheck();

value = new ByteList(bytes);
value = new ByteList(bytes, copy);
shareLevel = SHARE_LEVEL_NONE;

value.invalidate();
@@ -3939,7 +3939,7 @@ private boolean end_with_pCommon(IRubyObject tmp) {
return false;
}

private static final ByteList SPACE_BYTELIST = new ByteList(ByteList.plain(" "));
private static final ByteList SPACE_BYTELIST = new ByteList(new byte[] { ' ' }, false);

private IRubyObject justify19(ThreadContext context, IRubyObject arg0, int jflag) {
Ruby runtime = context.runtime;
@@ -5444,7 +5444,7 @@ public IRubyObject freeze(ThreadContext context) {
* @deprecated
*/
public void setValue(CharSequence value) {
view(ByteList.plain(value));
view(ByteList.plain(value), false);
}

public void setValue(ByteList value) {
42 changes: 16 additions & 26 deletions core/src/main/java/org/jruby/ext/socket/RubyBasicSocket.java
Original file line number Diff line number Diff line change
@@ -57,7 +57,6 @@
import org.jruby.ast.util.ArgsUtil;
import org.jruby.ext.fcntl.FcntlLibrary;
import org.jruby.platform.Platform;
import org.jruby.runtime.Arity;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
@@ -200,51 +199,45 @@ private IRubyObject recv(ThreadContext context, IRubyObject length,

@JRubyMethod
public IRubyObject recv_nonblock(ThreadContext context, IRubyObject length) {
return recv_nonblock(context, length, context.nil, context.nil, false);
return recv_nonblock(context, length, context.nil, /* str */ null, true);
}

@JRubyMethod(required = 1, optional = 3) // (length) required = 1 handled above
public IRubyObject recv_nonblock(ThreadContext context, IRubyObject[] args) {
Ruby runtime = context.runtime;
int argc = args.length;
IRubyObject opts = ArgsUtil.getOptionsArg(context.runtime, args);
IRubyObject opts = ArgsUtil.getOptionsArg(runtime, args);
if (!opts.isNil()) argc--;

IRubyObject length = context.nil;
IRubyObject flags = length;
IRubyObject str = length;
IRubyObject length, flags, str;
length = flags = context.nil; str = null;

switch (argc) {
case 3:
str = args[2];
case 2:
flags = args[1];
case 1:
length = args[0];
case 3: str = args[2];
case 2: flags = args[1];
case 1: length = args[0];
}

boolean exception = ArgsUtil.extractKeywordArg(context, "exception", opts) != runtime.getFalse();

return recv_nonblock(context, length, flags, str, exception);
}

protected IRubyObject recv_nonblock(ThreadContext context, IRubyObject length,
IRubyObject flags, IRubyObject str, boolean ex) {
Ruby runtime = context.runtime;

protected final IRubyObject recv_nonblock(ThreadContext context,
IRubyObject length, IRubyObject flags, IRubyObject str, final boolean exception) {
// TODO: implement flags
final ByteBuffer buffer = ByteBuffer.allocate(RubyNumeric.fix2int(length));

ByteList bytes = doReceiveNonblock(context, buffer);

if (bytes == null) {
if (!ex) return runtime.newSymbol("wait_readable");
if (!exception) return context.runtime.newSymbol("wait_readable");
throw context.runtime.newErrnoEAGAINReadableError("recvfrom(2)");
}

if (str != null && !str.isNil()) {
str = str.convertToString();
((RubyString)str).setValue(bytes);
((RubyString) str).setValue(bytes);
return str;
}
return RubyString.newString(context.runtime, bytes);
@@ -504,7 +497,6 @@ public IRubyObject readmsg_nonblock(ThreadContext context, IRubyObject[] args) {
}

private ByteList doReceive(ThreadContext context, final ByteBuffer buffer) {
Ruby runtime = context.runtime;
OpenFile fptr;

fptr = getOpenFile();
@@ -517,8 +509,7 @@ private ByteList doReceive(ThreadContext context, final ByteBuffer buffer) {

if (read == 0) return null;

return new ByteList(buffer.array(), 0, buffer.position());

return new ByteList(buffer.array(), 0, buffer.position(), false);
}
catch (IOException e) {
// All errors to sysread should be SystemCallErrors, but on a closed stream
@@ -534,8 +525,7 @@ private ByteList doReceive(ThreadContext context, final ByteBuffer buffer) {
}
}

public ByteList doReceiveNonblock(ThreadContext context, final ByteBuffer buffer) {
Ruby runtime = context.runtime;
protected final ByteList doReceiveNonblock(ThreadContext context, final ByteBuffer buffer) {
Channel channel = getChannel();

if ( ! (channel instanceof SelectableChannel) ) {
@@ -557,8 +547,8 @@ public ByteList doReceiveNonblock(ThreadContext context, final ByteBuffer buffer
selectable.configureBlocking(oldBlocking);
}
}
catch(IOException e) {
throw runtime.newIOErrorFromException(e);
catch (IOException e) {
throw context.runtime.newIOErrorFromException(e);
}
}
}
@@ -791,7 +781,7 @@ public static IRubyObject set_do_not_reverse_lookup(IRubyObject recv, IRubyObjec
return set_do_not_reverse_lookup(recv.getRuntime().getCurrentContext(), recv, flag);
}

private static final ByteList FORMAT_SMALL_I = new ByteList(ByteList.plain("i"));
private static final ByteList FORMAT_SMALL_I = new ByteList(new byte[] { 'i' }, false);
protected MulticastStateManager multicastStateManager = null;

// By default we always reverse lookup unless do_not_reverse_lookup set.
110 changes: 54 additions & 56 deletions core/src/main/java/org/jruby/ext/socket/RubyUDPSocket.java
Original file line number Diff line number Diff line change
@@ -202,7 +202,7 @@ public IRubyObject connect(ThreadContext context, IRubyObject host, IRubyObject

@JRubyMethod
public IRubyObject recvfrom_nonblock(ThreadContext context, IRubyObject length) {
return recv_nonblock(context, length, context.nil, context.nil, false);
return recv_nonblock(context, length, context.nil, /* str */ null, true);
}

@JRubyMethod(required = 1, optional = 3) // (length) required = 1 handled above
@@ -212,40 +212,44 @@ public IRubyObject recvfrom_nonblock(ThreadContext context, IRubyObject[] args)
IRubyObject opts = ArgsUtil.getOptionsArg(context.runtime, args);
if (!opts.isNil()) argc--;

IRubyObject length = context.nil;
IRubyObject flags = length;
IRubyObject str = length;
IRubyObject length, flags, str;
length = flags = str = context.nil;

switch (argc) {
case 3:
str = args[2];
case 2:
flags = args[1];
case 1:
length = args[0];
case 3: str = args[2];
case 2: flags = args[1];
case 1: length = args[0];
}

boolean exception = ArgsUtil.extractKeywordArg(context, "exception", opts) != runtime.getFalse();

return recvfrom_nonblock(context, length, flags, str, exception);
}

public IRubyObject recvfrom_nonblock(ThreadContext context, IRubyObject _length, IRubyObject _flags, IRubyObject str, boolean ex) {
private IRubyObject recvfrom_nonblock(ThreadContext context,
IRubyObject length, IRubyObject flags, IRubyObject str, boolean exception) {
final Ruby runtime = context.runtime;

try {
int length = RubyNumeric.fix2int(_length);
ReceiveTuple tuple = doReceiveNonblockTuple(runtime, RubyNumeric.fix2int(length));

ReceiveTuple tuple = doReceiveNonblockTuple(runtime, length, ex);
if (tuple == null) {
if (!exception) return context.runtime.newSymbol("wait_readable");
throw context.runtime.newErrnoEAGAINReadableError("recvfrom(2)");
}

// TODO: make this efficient
if (!str.isNil()) {
tuple.result = str.convertToString().replace19(tuple.result);
if (str != null && !str.isNil()) {
str = str.convertToString();
((RubyString) str).setValue(tuple.result.getByteList());
}
else {
str = tuple.result;
}

IRubyObject addressArray = addrFor(context, tuple.sender, false);

return runtime.newArray(tuple.result, addressArray);
return runtime.newArray(str, addressArray);
}
catch (UnknownHostException e) {
throw SocketUtils.sockerr(runtime, "recvfrom: name or service not known");
@@ -390,13 +394,11 @@ public static IRubyObject open(ThreadContext context, IRubyObject recv, IRubyObj
* Overrides IPSocket#recvfrom
*/
@Override
public IRubyObject recvfrom(ThreadContext context, IRubyObject _length) {
public IRubyObject recvfrom(ThreadContext context, IRubyObject length) {
final Ruby runtime = context.runtime;

try {
int length = RubyNumeric.fix2int(_length);

ReceiveTuple tuple = doReceiveTuple(runtime, length, true);
ReceiveTuple tuple = doReceiveTuple(runtime, false, RubyNumeric.fix2int(length));

IRubyObject addressArray = addrFor(context, tuple.sender, false);

@@ -430,11 +432,11 @@ public IRubyObject recvfrom(ThreadContext context, IRubyObject _length, IRubyObj
* Overrides BasicSocket#recv
*/
@Override
public IRubyObject recv(ThreadContext context, IRubyObject _length) {
public IRubyObject recv(ThreadContext context, IRubyObject length) {
final Ruby runtime = context.runtime;

try {
return doReceive(runtime, RubyNumeric.fix2int(_length));
return doReceive(runtime, false, RubyNumeric.fix2int(length), null);
}
catch (IOException e) { // SocketException
throw runtime.newIOErrorFromException(e);
@@ -454,69 +456,65 @@ public IRubyObject recv(ThreadContext context, IRubyObject _length, IRubyObject
return recv(context, _length);
}

private ReceiveTuple doReceiveTuple(Ruby runtime, int length, boolean ex) throws IOException {
private ReceiveTuple doReceiveTuple(final Ruby runtime, final boolean non_block, int length) throws IOException {
ReceiveTuple tuple = new ReceiveTuple();

final IRubyObject result;
if (this.multicastStateManager == null) {
doReceive(runtime, length, ex, tuple);
result = doReceive(runtime, non_block, length, tuple);
} else {
doReceiveMulticast(runtime, length, ex, tuple);
result = doReceiveMulticast(runtime, non_block, length, tuple);
}

return tuple;
return result == null ? null : tuple; // need to return null for non_block (if op would block)
}

private ReceiveTuple doReceiveNonblockTuple(Ruby runtime, int length, boolean ex) throws IOException {
DatagramChannel channel = (DatagramChannel)getChannel();
private ReceiveTuple doReceiveNonblockTuple(Ruby runtime, int length) throws IOException {
DatagramChannel channel = (DatagramChannel) getChannel();

synchronized (channel.blockingLock()) {
boolean oldBlocking = channel.isBlocking();

channel.configureBlocking(false);

try {
return doReceiveTuple(runtime, length, ex);
return doReceiveTuple(runtime, true, length);
}
finally {
channel.configureBlocking(oldBlocking);
}
}
}

private static class ReceiveTuple {
private static final class ReceiveTuple {
ReceiveTuple() {}
ReceiveTuple(RubyString result, InetSocketAddress sender) {
this.result = result;
this.sender = sender;
}

//ReceiveTuple(RubyString result, InetSocketAddress sender) {
// this.result = result;
// this.sender = sender;
//}

RubyString result;
InetSocketAddress sender;
}

private IRubyObject doReceive(Ruby runtime, int length) throws IOException {
return doReceive(runtime, length, true, null);
}

private IRubyObject doReceive(Ruby runtime, int length, boolean ex, ReceiveTuple tuple) throws IOException {
DatagramChannel channel = (DatagramChannel)getChannel();
private IRubyObject doReceive(final Ruby runtime, final boolean non_block,
int length, ReceiveTuple tuple) throws IOException {
DatagramChannel channel = (DatagramChannel) getChannel();

ByteBuffer buf = ByteBuffer.allocate(length);

InetSocketAddress sender = (InetSocketAddress)channel.receive(buf);

if (sender == null) {
// noblocking receive
if (!ex) return runtime.newSymbol("wait_readable");
throw runtime.newErrnoEAGAINReadableError("recvfrom(2) would block");
}
InetSocketAddress sender = (InetSocketAddress) channel.receive(buf);

// see JRUBY-4678
if (sender == null) {
throw runtime.newErrnoECONNRESETError();
if ( non_block ) { // non-blocking receive
return null; // :wait_readable or "recvfrom(2) would block"
}
else { // see JRUBY-4678
throw runtime.newErrnoECONNRESETError();
}
}

RubyString result = runtime.newString(new ByteList(buf.array(), 0, buf.position()));
RubyString result = runtime.newString(new ByteList(buf.array(), 0, buf.position(), false));

if (tuple != null) {
tuple.result = result;
@@ -526,17 +524,17 @@ private IRubyObject doReceive(Ruby runtime, int length, boolean ex, ReceiveTuple
return result;
}

private IRubyObject doReceiveMulticast(Ruby runtime, int length, boolean ex, ReceiveTuple tuple) throws IOException {
byte[] buf2 = new byte[length];
ByteBuffer recv = ByteBuffer.wrap(buf2);
private IRubyObject doReceiveMulticast(final Ruby runtime, final boolean non_block,
int length, ReceiveTuple tuple) throws IOException {
ByteBuffer recv = ByteBuffer.wrap(new byte[length]);
SocketAddress address;

DatagramChannel channel = this.multicastStateManager.getMulticastSocket().getChannel();

address = channel.receive(recv);

if (address == null) {
if (!ex) return runtime.newSymbol("wait_readable");
if ( non_block ) return null; // :wait_readable or raise WaitReadable
throw runtime.newErrnoEAGAINReadableError("multicast UDP does not support nonblocking");
}

@@ -548,7 +546,7 @@ private IRubyObject doReceiveMulticast(Ruby runtime, int length, boolean ex, Rec
}

recv.flip();
RubyString result = runtime.newString(new ByteList(recv.array(), recv.position(), recv.limit()));
RubyString result = runtime.newString(new ByteList(recv.array(), recv.position(), recv.limit(), false));

if (tuple != null) {
tuple.result = result;
Loading