Skip to content

Commit

Permalink
[Truffle] Fix at_exit hooks to allow concurrent and nested interactions.
Browse files Browse the repository at this point in the history
  • Loading branch information
eregon committed May 15, 2015
1 parent df5438f commit 87ef166
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 26 deletions.
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/kernel/at_exit_tags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,4 @@ slow:Kernel.at_exit runs after all other code
slow:Kernel.at_exit runs in reverse order of registration
slow:Kernel.at_exit allows calling exit inside at_exit handler
slow:Kernel.at_exit gives access to the last raised exception
fails:Kernel.at_exit allows calling exit inside at_exit handler
fails:Kernel.at_exit runs in reverse order of registration
fails:Kernel.at_exit runs after all other code
fails:Kernel.at_exit gives access to the last raised exception
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,43 @@

import org.jruby.truffle.runtime.core.RubyProc;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Deque;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentLinkedDeque;

public class AtExitManager {

private final List<RubyProc> runOnExit = new LinkedList<>();
private final List<RubyProc> runOnExitAlways = new LinkedList<>();
private final Deque<RubyProc> runOnExit = new ConcurrentLinkedDeque<>();
private final Deque<RubyProc> runOnExitAlways = new ConcurrentLinkedDeque<>();

public synchronized void add(RubyProc block, boolean always) {
public void add(RubyProc block, boolean always) {
if (always) {
runOnExitAlways.add(block);
runOnExitAlways.push(block);
} else {
runOnExit.add(block);
runOnExit.push(block);
}
}

public synchronized void run(boolean normalExit) {
if (normalExit) {
Collections.reverse(runOnExit);

for (RubyProc block : runOnExit) {
try {
block.rootCall();
} catch (Exception e) {
}
public void run(boolean normalExit) {
try {
if (normalExit) {
runExitHooks(runOnExit);
}
} finally {
runExitHooks(runOnExitAlways);
}
}

Collections.reverse(runOnExitAlways);

for (RubyProc block : runOnExitAlways) {
private void runExitHooks(Deque<RubyProc> stack) {
while (true) {
RubyProc block;
try {
block.rootCall();
} catch (Exception e) {
block = stack.pop();
} catch (NoSuchElementException e) {
break;
}

block.rootCall();
}
}

Expand Down

0 comments on commit 87ef166

Please sign in to comment.