Skip to content

Instantly share code, notes, and snippets.

@quasicomputational
Created March 12, 2019 17:44
Show Gist options
  • Save quasicomputational/140c08865b5cdb63f11e230dc8392d65 to your computer and use it in GitHub Desktop.
Save quasicomputational/140c08865b5cdb63f11e230dc8392d65 to your computer and use it in GitHub Desktop.
// When should a new session identifier be generated? If it's done unconditionally, this can cause a double free when the extension reloads, as we think the extension pages' references are stale. If it's done in onStartup, then we mightn't clean up stale references as promptly as we could due to bug 1534700 (which is less bad, but annoying).
session = generateSessionIdentifier();
messaged = () => {
return Promise.resolve(session);
};
browser.runtime.onMessage.addListener(messaged);
for (const [referenceId, record] in db.store(REFERENCES).getAll()) {
if (record.session === session) {
continue;
}
decreaseRefcount(record.node);
db.store(REFERENCES).delete(referenceId);
}
in a transaction {
node = foo();
}
// Problem: the node is a reference to a refcounted structure stored in the IndexedDB, but this script isn't holding a reference to it! Another script might concurrently free it and cause a dangling reference.
doStuff(node);
in a transaction {
node = foo();
increaseRefcount(node);
}
doStuff(node);
// Consider what happens if the browser crashes (or the power dies, or anything else) here: the refcount's been incremented, but now the associated decrement will never happen! The reference is leaked and the node this script is operating on will live in the database forever.
in a transaction {
decreaseRefcount(node);
}
session = await browser.runtime.sendMessage();
in a transaction {
node = foo();
increaseRefcount(node);
referenceId = db.store(REFERENCES).add({ node, session });
}
doStuff(node);
in a transaction {
decreaseRefcount(node);
db.store(REFERENCES).delete(referenceId);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment