Skip to content

Commit

Permalink
fix(swingset): hold strong reference to all device nodes
Browse files Browse the repository at this point in the history
Don't let them get collected, we don't do GC tracking for them, and there
aren't very many of them yet.
  • Loading branch information
warner committed May 25, 2021
1 parent fe93b3d commit 2a07d8e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/SwingSet/src/kernel/liveSlots.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ function build(
const slotToVal = new Map(); // vref -> WeakRef(object)
const exportedRemotables = new Set(); // objects
const pendingPromises = new Set(); // Promises
const importedDevices = new Set(); // device nodes
const safetyPins = new Set(); // temporary
const deadSet = new Set(); // vrefs that are finalized but not yet reported

Expand Down Expand Up @@ -487,6 +488,7 @@ function build(
}
} else if (type === 'device') {
val = makeDeviceNode(slot, iface);
importedDevices.add(val);
} else {
assert.fail(X`unrecognized slot type '${type}'`);
}
Expand Down
28 changes: 28 additions & 0 deletions packages/SwingSet/test/test-liveslots.js
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,34 @@ test('disavow', async t => {
t.deepEqual(log, []);
});

test('liveslots retains device nodes', async t => {
const { syscall } = buildSyscall();
let watch;
const recognize = new WeakSet(); // real WeakSet
const success = [];
function build(_vatPowers) {
const root = Far('root', {
first(dn) {
watch = new WeakRef(dn);
recognize.add(dn);
},
second(dn) {
success.push(recognize.has(dn));
},
});
return root;
}

const dispatch = makeDispatch(syscall, build);
const rootA = 'o+0';
const device = 'd-1';
await dispatch(makeMessage(rootA, 'first', capargsOneSlot(device)));
await gcAndFinalize();
t.truthy(watch.deref(), 'Device node not retained');
await dispatch(makeMessage(rootA, 'second', capargsOneSlot(device)));
t.deepEqual(success, [true]);
});

test('GC operations', async t => {
const { log, syscall } = buildSyscall();

Expand Down

0 comments on commit 2a07d8e

Please sign in to comment.