Skip to content

Commit

Permalink
fix: Resolver-side resolved promise retirement
Browse files Browse the repository at this point in the history
  • Loading branch information
FUDCo committed May 18, 2020
1 parent dc0aec9 commit 7cb2984
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 14 deletions.
14 changes: 8 additions & 6 deletions packages/SwingSet/src/kernel/kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,12 @@ export default function buildKernel(kernelEndowments) {
return harden({ body: JSON.stringify(s), slots: [] });
}

function notifySubscribersAndQueue(kpid, subscribers, queue) {
function notifySubscribersAndQueue(kpid, resolvingVatID, subscribers, queue) {
insistKernelType('promise', kpid);
for (const vatID of subscribers) {
notify(vatID, kpid);
if (vatID !== resolvingVatID) {
notify(vatID, kpid);
}
}
// re-deliver msg to the now-settled promise, which will forward or
// reject depending on the new state of the promise
Expand Down Expand Up @@ -163,7 +165,7 @@ export default function buildKernel(kernelEndowments) {
const p = getResolveablePromise(kpid, vatID);
const { subscribers, queue } = p;
kernelKeeper.fulfillKernelPromiseToPresence(kpid, targetSlot);
notifySubscribersAndQueue(kpid, subscribers, queue);
notifySubscribersAndQueue(kpid, vatID, subscribers, queue);
// todo: some day it'd be nice to delete the promise table entry now. To
// do that correctly, we must make sure no vats still hold pointers to
// it, which means vats must drop their refs when they get notified about
Expand All @@ -179,7 +181,7 @@ export default function buildKernel(kernelEndowments) {
const p = getResolveablePromise(kpid, vatID);
const { subscribers, queue } = p;
kernelKeeper.fulfillKernelPromiseToData(kpid, data);
notifySubscribersAndQueue(kpid, subscribers, queue);
notifySubscribersAndQueue(kpid, vatID, subscribers, queue);
}

function reject(vatID, kpid, data) {
Expand All @@ -189,7 +191,7 @@ export default function buildKernel(kernelEndowments) {
const p = getResolveablePromise(kpid, vatID);
const { subscribers, queue } = p;
kernelKeeper.rejectKernelPromise(kpid, data);
notifySubscribersAndQueue(kpid, subscribers, queue);
notifySubscribersAndQueue(kpid, vatID, subscribers, queue);
}

const syscallManager = {
Expand Down Expand Up @@ -297,7 +299,7 @@ export default function buildKernel(kernelEndowments) {
const p = getKernelResolveablePromise(kpid);
const { subscribers, queue } = p;
kernelKeeper.rejectKernelPromise(kpid, errorData);
notifySubscribersAndQueue(kpid, subscribers, queue);
notifySubscribersAndQueue(kpid, undefined, subscribers, queue);
}

async function deliverToTarget(target, msg) {
Expand Down
25 changes: 17 additions & 8 deletions packages/SwingSet/src/kernel/liveSlots.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,14 @@ function build(syscall, _state, makeRoot, forVatID) {
}
}

function retirePromiseID(promiseID) {
lsdebug(`Retiring ${forVatID}:${promiseID}`);
importedPromisesByPromiseID.delete(promiseID);
const p = slotToVal.get(promiseID);
valToSlot.delete(p);
slotToVal.delete(promiseID);
}

function thenResolve(promiseID) {
insistVatType('promise', promiseID);
return res => {
Expand All @@ -398,6 +406,9 @@ function build(syscall, _state, makeRoot, forVatID) {
lsdebug(` ser ${ser.body} ${JSON.stringify(ser.slots)}`);
// find out what resolution category we're using
const unser = JSON.parse(ser.body);
if (importedPromisesByPromiseID.has(promiseID)) {
importedPromisesByPromiseID.get(promiseID).res(res);
}
if (
Object(unser) === unser &&
QCLASS in unser &&
Expand All @@ -406,10 +417,12 @@ function build(syscall, _state, makeRoot, forVatID) {
const slot = ser.slots[unser.index];
insistVatType('object', slot);
syscall.fulfillToPresence(promiseID, slot);
retirePromiseID(promiseID);
} else {
// if it resolves to data, .thens fire but kernel-queued messages are
// rejected, because you can't send messages to data
syscall.fulfillToData(promiseID, ser);
retirePromiseID(promiseID);
}

// TODO (for chip): the kernel currently notifies all subscribers of a
Expand Down Expand Up @@ -440,7 +453,11 @@ function build(syscall, _state, makeRoot, forVatID) {
harden(rej);
lsdebug(`ls thenReject fired`, rej);
const ser = m.serialize(rej);
if (importedPromisesByPromiseID.has(promiseID)) {
importedPromisesByPromiseID.get(promiseID).rej(rej);
}
syscall.reject(promiseID, ser);
retirePromiseID(promiseID);
// TODO (for chip): this is also a double-rejection until the
// retire-promises branch lands. Delete this comment when that happens.
const pRec = importedPromisesByPromiseID.get(promiseID);
Expand All @@ -450,14 +467,6 @@ function build(syscall, _state, makeRoot, forVatID) {
};
}

function retirePromiseID(promiseID) {
lsdebug(`Retiring ${forVatID}:${promiseID}`);
importedPromisesByPromiseID.delete(promiseID);
const p = slotToVal.get(promiseID);
valToSlot.delete(p);
slotToVal.delete(promiseID);
}

function notifyFulfillToData(promiseID, data) {
insistCapData(data);
lsdebug(
Expand Down
3 changes: 3 additions & 0 deletions packages/SwingSet/src/kernel/vatManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export default function makeVatManager(
kdebug(
`syscall[${vatID}].fulfillToPresence(${promiseID} / ${kpid}) = ${slot} / ${targetSlot})`,
);
vatKeeper.deleteCListEntry(kpid, promiseID);
syscallManager.fulfillToPresence(vatID, kpid, targetSlot);
}

Expand All @@ -181,6 +182,7 @@ export default function makeVatManager(
data.body
} ${JSON.stringify(data.slots)}/${JSON.stringify(kernelSlots)}`,
);
vatKeeper.deleteCListEntry(kpid, promiseID);
syscallManager.fulfillToData(vatID, kpid, kernelData);
}

Expand All @@ -195,6 +197,7 @@ export default function makeVatManager(
data.body
} ${JSON.stringify(data.slots)}/${JSON.stringify(kernelSlots)}`,
);
vatKeeper.deleteCListEntry(kpid, promiseID);
syscallManager.reject(vatID, kpid, kernelData);
}

Expand Down

0 comments on commit 7cb2984

Please sign in to comment.