refactor: use WeakRef on renderer side of remote (#24037)

This commit is contained in:
Jeremy Rose 2020-06-12 15:50:03 -07:00 committed by GitHub
parent 178e46cd23
commit 379bb174e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 26 additions and 117 deletions

View file

@ -11,7 +11,28 @@ const { hasSwitch } = process.electronBinding('command_line');
const { NativeImage } = process.electronBinding('native_image');
const callbacksRegistry = new CallbacksRegistry();
const remoteObjectCache = v8Util.createIDWeakMap();
const remoteObjectCache = new Map();
const finalizationRegistry = new (window as any).FinalizationRegistry((id: number) => {
const ref = remoteObjectCache.get(id);
if (ref !== undefined && ref.deref() === undefined) {
remoteObjectCache.delete(id);
ipcRendererInternal.send('ELECTRON_BROWSER_DEREFERENCE', contextId, id, 0);
}
});
function getCachedRemoteObject (id: number) {
const ref = remoteObjectCache.get(id);
if (ref !== undefined) {
const deref = ref.deref();
if (deref !== undefined) return deref;
}
}
function setCachedRemoteObject (id: number, value: any) {
const wr = new (window as any).WeakRef(value);
remoteObjectCache.set(id, wr);
finalizationRegistry.register(value, id);
return value;
}
// An unique ID that can represent current context.
const contextId = v8Util.getHiddenValue<string>(global, 'contextId');
@ -234,8 +255,9 @@ function metaToValue (meta: MetaType): any {
if (meta.value.type === 'error') { throw metaToError(meta.value); } else { throw new Error(`Unexpected value type in exception: ${meta.value.type}`); }
} else {
let ret;
if ('id' in meta && remoteObjectCache.has(meta.id)) {
return remoteObjectCache.get(meta.id);
if ('id' in meta) {
const cached = getCachedRemoteObject(meta.id);
if (cached !== undefined) { return cached; }
}
// A shadow class to represent the remote function object.
@ -262,9 +284,8 @@ function metaToValue (meta: MetaType): any {
}
// Track delegate obj's lifetime & tell browser to clean up when object is GCed.
v8Util.setRemoteObjectFreer(ret, contextId, meta.id);
v8Util.setHiddenValue(ret, 'electronId', meta.id);
remoteObjectCache.set(meta.id, ret);
setCachedRemoteObject(meta.id, ret);
return ret;
}
}