From 2a07d8e03a96bb6d370040b39f54e338484efe75 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Sun, 23 May 2021 18:58:59 -0700 Subject: [PATCH] fix(swingset): hold strong reference to all device nodes Don't let them get collected, we don't do GC tracking for them, and there aren't very many of them yet. --- packages/SwingSet/src/kernel/liveSlots.js | 2 ++ packages/SwingSet/test/test-liveslots.js | 28 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/packages/SwingSet/src/kernel/liveSlots.js b/packages/SwingSet/src/kernel/liveSlots.js index b739aeff869..84335ae845c 100644 --- a/packages/SwingSet/src/kernel/liveSlots.js +++ b/packages/SwingSet/src/kernel/liveSlots.js @@ -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 @@ -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}'`); } diff --git a/packages/SwingSet/test/test-liveslots.js b/packages/SwingSet/test/test-liveslots.js index b255973e866..41ec69857c4 100644 --- a/packages/SwingSet/test/test-liveslots.js +++ b/packages/SwingSet/test/test-liveslots.js @@ -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();