Close unhandled ports

This commit is contained in:
Nils Maier 2019-10-02 09:37:24 +02:00
parent 9caad6b3a5
commit 4ba7bb530d
4 changed files with 28 additions and 15 deletions

View File

@ -8,32 +8,35 @@ import {runtime, tabs, RawPort, MessageSender} from "./browser";
export class Port extends EventEmitter { export class Port extends EventEmitter {
private port: RawPort | null; private port: RawPort | null;
private disconnected = false;
constructor(port: RawPort) { constructor(port: RawPort) {
super(); super();
this.port = port; this.port = port;
let disconnected = false;
const disconnect = () => {
if (disconnected) {
return;
}
disconnected = true;
this.port = null; // Break the cycle
this.emit("disconnect", this, port);
};
// Nasty firefox bug, thus listen for tab removal explicitly // Nasty firefox bug, thus listen for tab removal explicitly
if (port.sender && port.sender.tab && port.sender.tab.id) { if (port.sender && port.sender.tab && port.sender.tab.id) {
const otherTabId = port.sender.tab.id; const otherTabId = port.sender.tab.id;
const tabListener = function(tabId: number) { const tabListener = (tabId: number) => {
if (tabId !== otherTabId) { if (tabId !== otherTabId) {
return; return;
} }
disconnect(); this.disconnect();
}; };
tabs.onRemoved.addListener(tabListener); tabs.onRemoved.addListener(tabListener);
} }
port.onMessage.addListener(this.onMessage.bind(this)); port.onMessage.addListener(this.onMessage.bind(this));
port.onDisconnect.addListener(disconnect); port.onDisconnect.addListener(this.disconnect.bind(this));
}
disconnect() {
if (this.disconnected) {
return;
}
this.disconnected = true;
const {port} = this;
this.port = null; // Break the cycle
this.emit("disconnect", this, port);
} }
get name() { get name() {
@ -120,6 +123,9 @@ export const Bus = new class extends EventEmitter {
port.disconnect(); port.disconnect();
return; return;
} }
this.ports.emit(port.name, new Port(port)); const wrapped = new Port(port);
if (!this.ports.emit(port.name, wrapped)) {
wrapped.disconnect();
}
} }
}(); }();

View File

@ -93,6 +93,7 @@ export class Manager extends EventEmitter {
this.ports.delete(mport); this.ports.delete(mport);
}); });
this.ports.add(mport); this.ports.add(mport);
return true;
}); });
Limits.on("changed", () => { Limits.on("changed", () => {
this.resetScheduler(); this.resetScheduler();

View File

@ -101,7 +101,10 @@ export async function select(links: BaseItem[], media: BaseItem[]) {
tracker.track(window.id, null); tracker.track(window.id, null);
try { try {
const port = await Promise.race<Port>([ const port = await Promise.race<Port>([
new Promise<Port>(resolve => Bus.oncePort("select", resolve)), new Promise<Port>(resolve => Bus.oncePort("select", port => {
resolve(port);
return true;
})),
timeout<Port>(5 * 1000)]); timeout<Port>(5 * 1000)]);
if (!port.isSelf) { if (!port.isSelf) {
throw Error("Invalid sender connected"); throw Error("Invalid sender connected");

View File

@ -24,7 +24,10 @@ export async function single(item: BaseItem | null) {
tracker.track(window.id, null); tracker.track(window.id, null);
try { try {
const port: Port = await Promise.race<Port>([ const port: Port = await Promise.race<Port>([
new Promise<Port>(resolve => Bus.oncePort("single", resolve)), new Promise<Port>(resolve => Bus.oncePort("single", port => {
resolve(port);
return true;
})),
timeout<Port>(5 * 1000)]); timeout<Port>(5 * 1000)]);
if (!port.isSelf) { if (!port.isSelf) {
throw Error("Invalid sender connected"); throw Error("Invalid sender connected");