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

Commits on Jul 14, 2015

  1. [Truffle] Make ThreadManager.runOnce() private.

    * This is just an internal helper, there is no valid use case
      for stopping a blocking action based on any interrupt() or guest safepoint.
    eregon committed Jul 14, 2015
    Copy the full SHA
    79e2bd4 View commit details
  2. Copy the full SHA
    7e89610 View commit details
Original file line number Diff line number Diff line change
@@ -635,7 +635,7 @@ public Object select(RubyBasicObject readables, RubyBasicObject writables, RubyB
readableSet.set(fd);
}

final int result = getContext().getThreadManager().runOnce(new ThreadManager.BlockingActionWithoutGlobalLock<Integer>() {
final int result = getContext().getThreadManager().runUntilResult(new ThreadManager.BlockingActionWithoutGlobalLock<Integer>() {
@Override
public Integer block() throws InterruptedException {
return nativeSockets().select(
@@ -669,7 +669,7 @@ public Object selectNilReadables(RubyBasicObject readables, RubyBasicObject writ
writableSet.set(fd);
}

final int result = getContext().getThreadManager().runOnce(new ThreadManager.BlockingActionWithoutGlobalLock<Integer>() {
final int result = getContext().getThreadManager().runUntilResult(new ThreadManager.BlockingActionWithoutGlobalLock<Integer>() {
@Override
public Integer block() throws InterruptedException {
return nativeSockets().select(
Original file line number Diff line number Diff line change
@@ -508,7 +508,7 @@ public Object waitPID(final int input_pid, boolean no_hang) {
final int finalOptions = options;

// retry:
pid = getContext().getThreadManager().runOnce(new ThreadManager.BlockingActionWithoutGlobalLock<Integer>() {
pid = getContext().getThreadManager().runUntilResult(new ThreadManager.BlockingActionWithoutGlobalLock<Integer>() {
@Override
public Integer block() throws InterruptedException {
return posix().waitpid(input_pid, statusReference, finalOptions);
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
package org.jruby.truffle.runtime.core;

import com.oracle.truffle.api.nodes.Node;

import org.jruby.RubyThread.Status;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.core.ProcNodes;
@@ -155,10 +156,17 @@ public Boolean block() throws InterruptedException {
}

public boolean join(final int timeoutInMillis) {
final boolean joined = manager.runOnce(new BlockingActionWithoutGlobalLock<Boolean>() {
final long start = System.currentTimeMillis();
final boolean joined = manager.runUntilResult(new BlockingActionWithoutGlobalLock<Boolean>() {
@Override
public Boolean block() throws InterruptedException {
return finished.await(timeoutInMillis, TimeUnit.MILLISECONDS);
long now = System.currentTimeMillis();
long waited = now - start;
if (waited >= timeoutInMillis) {
// We need to know whether countDown() was called and we do not want to block.
return finished.getCount() == 0;
}
return finished.await(timeoutInMillis - waited, TimeUnit.MILLISECONDS);
}
});

Original file line number Diff line number Diff line change
@@ -101,38 +101,23 @@ public <T> T runUntilResult(BlockingActionWithoutGlobalLock<T> action) {
T result = null;

do {
result = runOnce(action);
} while (result == null);
final RubyThread runningThread = leaveGlobalLock();
runningThread.setStatus(Status.SLEEP);

return result;
}

/**
* Runs {@code action} once.
* The action might be {@link Thread#interrupted()}, for instance by
* the {@link SafepointManager}, in which case null will be returned.
*
* @param action must not touch any Ruby state
* @return the return value from {@code action} or null if interrupted
*/
@TruffleBoundary
public <T> T runOnce(BlockingActionWithoutGlobalLock<T> action) {
T result = null;
final RubyThread runningThread = leaveGlobalLock();
runningThread.setStatus(Status.SLEEP);

try {
try {
result = action.block();
} finally {
runningThread.setStatus(Status.RUN);
// We need to enter the global lock before anything else!
enterGlobalLock(runningThread);
try {
result = action.block();
} finally {
runningThread.setStatus(Status.RUN);
// We need to enter the global lock before anything else!
enterGlobalLock(runningThread);
}
} catch (InterruptedException e) {
// We were interrupted, possibly by the SafepointManager.
context.getSafepointManager().pollFromBlockingCall(null);
}
} catch (InterruptedException e) {
// We were interrupted, possibly by the SafepointManager.
context.getSafepointManager().pollFromBlockingCall(null);
}
} while (result == null);

return result;
}