locking internalCall

This commit is contained in:
Danny Yoo 2011-12-09 22:31:36 -05:00
parent 4573dc701e
commit ac499e24f6
2 changed files with 49 additions and 16 deletions

View File

@ -458,11 +458,14 @@
// Creates a restarting function, that reschedules f in a context // Creates a restarting function, that reschedules f in a context
// with the old argcount in place. // with the old argcount in place.
// Meant to be used only by the trampoline. // Meant to be used only by the trampoline.
var makeRestartFunction = function(MACHINE, release) { var makeRestartFunction = function(MACHINE, release, pauseLock) {
var oldArgcount = MACHINE.a; var oldArgcount = MACHINE.a;
return function(f) { return function(f) {
MACHINE.a = oldArgcount; pauseLock.acquire(function(pauseReleaseLock) {
MACHINE._trampoline(f, false, release); MACHINE.a = oldArgcount;
MACHINE._trampoline(f, false, release);
pauseReleaseLock();
});
}; };
}; };
@ -555,8 +558,39 @@
return; return;
} }
} else if (e instanceof Pause) { } else if (e instanceof Pause) {
var restart = makeRestartFunction(that, release); var pauseLock = new ExclusiveLock();
e.onPause(restart); var oldArgcount = that.a;
var restarted = false;
var restart = function(f) {
pauseLock.acquire(function(releasePauseLock) {
restarted = true;
that.a = oldArgcount;
that._trampoline(f, false, release);
releasePauseLock();
});
};
var internalCall = function(proc, success, fail) {
if (restarted) {
return;
}
var args = [];
for (i = 3; i < arguments.length; i++) {
args.push(arguments[i]);
}
pauseLock.acquire(function(release) {
var newSuccess = function() {
success.apply(null, arguments);
release();
};
var newFail = function() {
fail.apply(null, arguments);
release();
};
baselib.functions.internalCallDuringPause.apply(
null, [that, proc, newSuccess, newFail].concat(args));
});
};
e.onPause(restart, internalCall);
return; return;
} else if (e instanceof HaltError) { } else if (e instanceof HaltError) {
that.running = false; that.running = false;

View File

@ -1171,7 +1171,7 @@
MACHINE.params.currentOutputPort = find(handlers, isWithOutputToHandler).outputPort; MACHINE.params.currentOutputPort = find(handlers, isWithOutputToHandler).outputPort;
} }
PAUSE(function(restart) { PAUSE(function(restart, internalCall) {
var onCleanRestart, onMessyRestart, var onCleanRestart, onMessyRestart,
startEventHandlers, stopEventHandlers, startEventHandlers, stopEventHandlers,
startEventHandler, stopEventHandler, startEventHandler, stopEventHandler,
@ -1260,7 +1260,7 @@
var onGoodWorldUpdate = var onGoodWorldUpdate =
function(newWorld) { function(newWorld) {
world = newWorld; world = newWorld;
stopWhen(MACHINE, stopWhen(internalCall,
world, world,
mockView, mockView,
function(shouldStop) { function(shouldStop) {
@ -1274,14 +1274,14 @@
fail); fail);
}; };
if (plt.baselib.arity.isArityMatching(racketWorldCallback.racketArity, 3)) { if (plt.baselib.arity.isArityMatching(racketWorldCallback.racketArity, 3)) {
racketWorldCallback(MACHINE, racketWorldCallback(internalCall,
world, world,
mockView, mockView,
data, data,
onGoodWorldUpdate, onGoodWorldUpdate,
fail); fail);
} else { } else {
racketWorldCallback(MACHINE, racketWorldCallback(internalCall,
world, world,
mockView, mockView,
onGoodWorldUpdate, onGoodWorldUpdate,
@ -1299,7 +1299,7 @@
// update, and have to do it from scratch. // update, and have to do it from scratch.
var nonce = Math.random(); var nonce = Math.random();
var originalMockView = view.getMockAndResetFocus(nonce); var originalMockView = view.getMockAndResetFocus(nonce);
toDraw(MACHINE, toDraw(internalCall,
world, world,
originalMockView, originalMockView,
function(newMockView) { function(newMockView) {
@ -1334,15 +1334,14 @@
}; };
var wrapFunction = function(proc) { var wrapFunction = function(proc) {
var f = function(MACHINE) { var f = function(internalCall) {
var success = arguments[arguments.length - 2]; var success = arguments[arguments.length - 2];
var fail = arguments[arguments.length - 1]; var fail = arguments[arguments.length - 1];
var args = [].slice.call(arguments, 1, arguments.length - 2); var args = [].slice.call(arguments, 1, arguments.length - 2);
return plt.baselib.functions.internalCallDuringPause.apply(null, return internalCall.apply(null,
[MACHINE, [proc,
proc, success,
success, fail].concat(args));
fail].concat(args));
}; };
f.racketArity = proc.racketArity; f.racketArity = proc.racketArity;
return f; return f;