From ac499e24f6891fde1b69141988d861292b780bad Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Fri, 9 Dec 2011 22:31:36 -0500 Subject: [PATCH] locking internalCall --- js-assembler/runtime-src/runtime.js | 44 +++++++++++++++++++++++++---- web-world/js-impl.js | 21 +++++++------- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/js-assembler/runtime-src/runtime.js b/js-assembler/runtime-src/runtime.js index 3863fe9..6dc6720 100644 --- a/js-assembler/runtime-src/runtime.js +++ b/js-assembler/runtime-src/runtime.js @@ -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; diff --git a/web-world/js-impl.js b/web-world/js-impl.js index 69ce92c..61989b3 100644 --- a/web-world/js-impl.js +++ b/web-world/js-impl.js @@ -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;