chasing a double-release
This commit is contained in:
parent
ccdb0c88f6
commit
46f314ea35
|
@ -128,16 +128,24 @@
|
|||
|
||||
var coerseClosureToJavaScript = function (v, MACHINE) {
|
||||
var f = function (succ, fail) {
|
||||
var args = [];
|
||||
var i;
|
||||
for (i = 0; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
|
||||
MACHINE.exclusiveLock.acquire(
|
||||
"js-as-closure",
|
||||
function(releaseLock) {
|
||||
succ = succ || function () {};
|
||||
fail = fail || function () {};
|
||||
|
||||
releaseLock();
|
||||
|
||||
if (!(baselib.arity.isArityMatching(v.racketArity, arguments.length - 2))) {
|
||||
if (!(baselib.arity.isArityMatching(v.racketArity, args.length - 2))) {
|
||||
var msg = baselib.format.format(
|
||||
"arity mismatch: ~s expected ~s argument(s) but received ~s",
|
||||
[v.displayName, v.racketArity, arguments.length - 2]);
|
||||
[v.displayName, v.racketArity, args.length - 2]);
|
||||
return fail(new baselib.exceptions.RacketError(
|
||||
msg,
|
||||
baselib.exceptions.makeExnFailContractArity(msg,
|
||||
|
@ -177,10 +185,10 @@
|
|||
|
||||
MACHINE.c.push(
|
||||
new baselib.frames.CallFrame(afterGoodInvoke, v));
|
||||
MACHINE.a = arguments.length - 2;
|
||||
MACHINE.a = args.length - 2;
|
||||
var i;
|
||||
for (i = 0; i < arguments.length - 2; i++) {
|
||||
MACHINE.e.push(arguments[arguments.length - 1 - i]);
|
||||
for (i = 0; i < args.length - 2; i++) {
|
||||
MACHINE.e.push(args[args.length - 1 - i]);
|
||||
}
|
||||
MACHINE.p = v;
|
||||
MACHINE.params['currentErrorHandler'] = function (MACHINE, e) {
|
||||
|
@ -191,7 +199,6 @@
|
|||
fail(e);
|
||||
|
||||
};
|
||||
releaseLock();
|
||||
MACHINE.trampoline(v.label);
|
||||
});
|
||||
};
|
||||
|
@ -222,15 +229,20 @@
|
|||
// internallCallDuringPause: call a Racket procedure and get its results.
|
||||
// The use assumes the machine is in a running-but-paused state.
|
||||
var internalCallDuringPause = function (MACHINE, proc, success, fail) {
|
||||
MACHINE.exclusiveLock.acquire(
|
||||
var args = [];
|
||||
var i;
|
||||
for (i = 0; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
MACHINE.exclusiveLock.acquire(
|
||||
"internal call during pause",
|
||||
function(releaseLock) {
|
||||
|
||||
releaseLock();
|
||||
var i;
|
||||
var oldArgcount, oldVal, oldProc, oldErrorHandler;
|
||||
if (! baselib.arity.isArityMatching(proc.racketArity, arguments.length - 4)) {
|
||||
if (! baselib.arity.isArityMatching(proc.racketArity, args.length - 4)) {
|
||||
var msg = baselib.format.format("arity mismatch: ~s expected ~s arguments, but received ~s",
|
||||
[proc.displayName, proc.racketArity, arguments.length - 4]);
|
||||
[proc.displayName, proc.racketArity, args.length - 4]);
|
||||
return fail(baselib.exceptions.makeExnFailContractArity(msg,
|
||||
MACHINE.captureContinuationMarks()));
|
||||
}
|
||||
|
@ -268,9 +280,9 @@
|
|||
|
||||
MACHINE.c.push(
|
||||
new baselib.frames.CallFrame(afterGoodInvoke, proc));
|
||||
MACHINE.a = arguments.length - 4;
|
||||
for (i = 0; i < arguments.length - 4; i++) {
|
||||
MACHINE.e.push(arguments[arguments.length - 1 - i]);
|
||||
MACHINE.a = args.length - 4;
|
||||
for (i = 0; i < args.length - 4; i++) {
|
||||
MACHINE.e.push(args[args.length - 1 - i]);
|
||||
}
|
||||
MACHINE.p = proc;
|
||||
MACHINE.params['currentErrorHandler'] = function (MACHINE, e) {
|
||||
|
@ -281,7 +293,6 @@
|
|||
fail(e);
|
||||
};
|
||||
|
||||
releaseLock();
|
||||
MACHINE.trampoline(proc.label);
|
||||
|
||||
} else {
|
||||
|
|
|
@ -191,29 +191,36 @@
|
|||
if (id === undefined) {
|
||||
id = ExclusiveLock.makeRandomNonce();
|
||||
}
|
||||
|
||||
var alreadyReleased = false;
|
||||
|
||||
// Allow for re-entrancy if the id is the same as the
|
||||
// entity who is locking.
|
||||
if (this.locked === false || this.locked === id) {
|
||||
this.locked = id;
|
||||
setTimeout(
|
||||
onAcquire.call(
|
||||
that,
|
||||
// releaseLock
|
||||
function() {
|
||||
onAcquire.call(
|
||||
that,
|
||||
// NOTE: the caller must release the lock or else deadlock!
|
||||
setTimeout(
|
||||
function() {
|
||||
var waiter;
|
||||
if (alreadyReleased) {
|
||||
throw new Error(
|
||||
"Internal error: trying to release the lock, but already released");
|
||||
}
|
||||
if (that.locked === false) {
|
||||
throw new Error(
|
||||
"Internal error: trying to unlock the lock, but already unlocked");
|
||||
}
|
||||
that.locked = false;
|
||||
alreadyReleased = true;
|
||||
if (that.waiters.length > 0) {
|
||||
waiter = that.waiters.shift();
|
||||
that.acquire(waiter.id, waiter.onAcquire);
|
||||
}
|
||||
});
|
||||
},
|
||||
0);
|
||||
}, 0);
|
||||
});
|
||||
} else {
|
||||
this.waiters.push({ id: id,
|
||||
onAcquire: onAcquire } );
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
(provide version)
|
||||
(: version String)
|
||||
|
||||
(define version "1.100")
|
||||
(define version "1.101")
|
||||
|
|
Loading…
Reference in New Issue
Block a user