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: 22432eb2eee4
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5a969273894b
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Oct 16, 2015

  1. [Truffle] Refactor runUntilTimeout and fix overflow.

    * Also make the timeout unit clearer.
    eregon committed Oct 16, 2015
    Copy the full SHA
    ac3f497 View commit details
  2. Copy the full SHA
    5a96927 View commit details
Original file line number Diff line number Diff line change
@@ -237,10 +237,10 @@ public IOEnsureOpenPrimitiveNode(RubyContext context, SourceSection sourceSectio
public DynamicObject ensureOpen(VirtualFrame frame, DynamicObject file) {
// TODO BJF 13-May-2015 Handle nil case
final int fd = Layouts.IO.getDescriptor(file);
if(fd == -1){
if (fd == -1) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().ioError("closed stream",this));
} else if (fd == -2){
} else if (fd == -2) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().ioError("shutdown stream",this));
}
@@ -272,34 +272,30 @@ public Object readIfAvailable(VirtualFrame frame, DynamicObject file, int number
fdSet.set(fd);

final Timeval timeoutObject = new DefaultNativeTimeval(jnr.ffi.Runtime.getSystemRuntime());
timeoutObject.setTime(new long[]{0, 0});
timeoutObject.setTime(new long[] { 0, 0 });

final int res = nativeSockets().select(fd + 1, fdSet.getPointer(),
PointerNodes.NULL_POINTER, PointerNodes.NULL_POINTER, timeoutObject);

if (res == 0) {
CompilerDirectives.transferToInterpreter();
ruby(frame, "raise IO::EAGAINWaitReadable");
}

if (res < 0) {
} else if (res < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().errnoError(posix().errno(), this));
}

final byte[] bytes = new byte[numberOfBytes];
final int bytesRead = posix().read(fd, bytes, numberOfBytes);

if (bytesRead == -1) {
if (bytesRead < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().errnoError(posix().errno(), this));
} else if (bytesRead == 0) { // EOF
return nil();
}

if (bytesRead == 0) {
return createString(new ByteList());
}

return createString(new ByteList(bytes));
return createString(new ByteList(bytes, 0, bytesRead, false));
}

}
@@ -432,7 +428,7 @@ public int write(DynamicObject file, DynamicObject string) {

int written = posix().write(fd, buffer, buffer.remaining());

if (written == -1) {
if (written < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().errnoError(posix().errno(), this));
}
@@ -553,22 +549,24 @@ public DynamicObject sysread(VirtualFrame frame, DynamicObject file, int length)
while (toRead > 0) {
getContext().getSafepointManager().poll(this);

final int readIteration = posix().read(fd, buffer, toRead);
final int bytesRead = posix().read(fd, buffer, toRead);

if (readIteration == -1) {
if (bytesRead < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().errnoError(posix().errno(), this));
} else if (bytesRead == 0) { // EOF
if (toRead == length) { // if EOF at first iteration
return nil();
} else {
break;
}
}

if (readIteration == 0) {
return nil();
}

buffer.position(readIteration);
toRead -= readIteration;
buffer.position(bytesRead);
toRead -= bytesRead;
}

return createString(new ByteList(buffer.array()));
return createString(new ByteList(buffer.array(), buffer.arrayOffset(), buffer.position(), false));
}

}
@@ -584,7 +582,7 @@ public IOSelectPrimitiveNode(RubyContext context, SourceSection sourceSection) {

@TruffleBoundary
@Specialization(guards = {"isRubyArray(readables)", "isNil(writables)", "isNil(errorables)"})
public Object select(DynamicObject readables, DynamicObject writables, DynamicObject errorables, int timeout) {
public Object select(DynamicObject readables, DynamicObject writables, DynamicObject errorables, int timeoutMicros) {
final Object[] readableObjects = ArrayOperations.toObjectArray(readables);
final int[] readableFds = getFileDescriptors(readables);

@@ -594,7 +592,7 @@ public Object select(DynamicObject readables, DynamicObject writables, DynamicOb
readableSet.set(fd);
}

final ThreadManager.ResultOrTimeout<Integer> result = getContext().getThreadManager().runUntilTimeout(this, timeout, new ThreadManager.BlockingTimeoutAction<Integer>() {
final ThreadManager.ResultOrTimeout<Integer> result = getContext().getThreadManager().runUntilTimeout(this, timeoutMicros, new ThreadManager.BlockingTimeoutAction<Integer>() {
@Override
public Integer block(Timeval timeoutToUse) throws InterruptedException {
final int result = nativeSockets().select(
@@ -622,10 +620,10 @@ public Integer block(Timeval timeoutToUse) throws InterruptedException {
return nil();
}

return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[]{
return Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), new Object[] {
getSetObjects(readableObjects, readableFds, readableSet),
Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0),
Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0)},
Layouts.ARRAY.createArray(getContext().getCoreLibrary().getArrayFactory(), null, 0) },
3);
}

Original file line number Diff line number Diff line change
@@ -115,10 +115,10 @@ public T getValue() {
public static class TimedOut<T> implements ResultOrTimeout<T> {
}

public <T> ResultOrTimeout<T> runUntilTimeout(Node currentNode, int timeout, final BlockingTimeoutAction<T> action) {
public <T> ResultOrTimeout<T> runUntilTimeout(Node currentNode, int timeoutMicros, final BlockingTimeoutAction<T> action) {
final Timeval timeoutToUse = new DefaultNativeTimeval(jnr.ffi.Runtime.getSystemRuntime());

if (timeout == 0) {
if (timeoutMicros == 0) {
timeoutToUse.setTime(new long[]{0, 0});

return new ResultWithinTime<>(runUntilResult(currentNode, new BlockingAction<T>() {
@@ -131,7 +131,7 @@ public T block() throws InterruptedException {
}));
} else {
final int pollTime = 500_000_000;
final long requestedTimeoutAt = System.nanoTime() + timeout * 1_000;
final long requestedTimeoutAt = System.nanoTime() + timeoutMicros * 1_000L;

return runUntilResult(currentNode, new BlockingAction<ResultOrTimeout<T>>() {

@@ -143,28 +143,22 @@ public ResultOrTimeout<T> block() throws InterruptedException {
return new TimedOut<>();
}

final boolean timeoutForPoll;
final long effectiveTimeout;

if (timeUntilRequestedTimeout < pollTime) {
timeoutForPoll = false;
effectiveTimeout = timeUntilRequestedTimeout;
} else {
timeoutForPoll = true;
effectiveTimeout = pollTime;
}

final boolean timeoutForPoll = pollTime <= timeUntilRequestedTimeout;
final long effectiveTimeout = Math.min(pollTime, timeUntilRequestedTimeout);
final long effectiveTimeoutMicros = effectiveTimeout / 1_000;
timeoutToUse.setTime(new long[]{effectiveTimeoutMicros / 1_000_000, effectiveTimeoutMicros % 1_000_000});
timeoutToUse.setTime(new long[] {
effectiveTimeoutMicros / 1_000_000,
effectiveTimeoutMicros % 1_000_000
});

final T result = action.block(timeoutToUse);

if (result == null && timeoutForPoll && requestedTimeoutAt - System.nanoTime() > 0) {
throw new InterruptedException();
}

if (result == null) {
return new TimedOut<>();
if (timeoutForPoll && (requestedTimeoutAt - System.nanoTime()) > 0) {
throw new InterruptedException();
} else {
return new TimedOut<>();
}
}

return new ResultWithinTime<>(result);