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
// with the old argcount in place.
// Meant to be used only by the trampoline.
var makeRestartFunction = function(MACHINE, release) {
var makeRestartFunction = function(MACHINE, release, pauseLock) {
var oldArgcount = MACHINE.a;
return function(f) {
MACHINE.a = oldArgcount;
MACHINE._trampoline(f, false, release);
pauseLock.acquire(function(pauseReleaseLock) {
MACHINE.a = oldArgcount;
MACHINE._trampoline(f, false, release);
pauseReleaseLock();
});
};
};
@ -555,8 +558,39 @@
return;
}
} else if (e instanceof Pause) {
var restart = makeRestartFunction(that, release);
e.onPause(restart);
var pauseLock = new ExclusiveLock();
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;
} else if (e instanceof HaltError) {
that.running = false;

View File

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