diff --git a/src/vs/base/parts/ipc/node/ipc.net.ts b/src/vs/base/parts/ipc/node/ipc.net.ts index c151fdbd3101b4c3ebad34cea6e30318cfc6905e..d1573af18287c3f498519bbf8729aaeb60ea2a9a 100644 --- a/src/vs/base/parts/ipc/node/ipc.net.ts +++ b/src/vs/base/parts/ipc/node/ipc.net.ts @@ -73,9 +73,10 @@ class Protocol implements IMessagePassingProtocol { } } -class RoutingChannelClient implements IRoutingChannelClient { +class RoutingChannelClient implements IRoutingChannelClient, IDisposable { - private ipcClients: { [id:string]: ChannelClient; }; + private ipcClients: { [id: string]: ChannelClient; }; + private onClientAdded = new Emitter(); constructor() { this.ipcClients = Object.create(null); @@ -83,27 +84,45 @@ class RoutingChannelClient implements IRoutingChannelClient { add(id: string, client: ChannelClient): void { this.ipcClients[id] = client; + this.onClientAdded.fire(); } remove(id: string): void { delete this.ipcClients[id]; } + private getClient(clientId: string): TPromise { + const getClientFn = (clientId: string, c: (client: IChannelClient) => void): boolean => { + let client = this.ipcClients[clientId]; + if (client) { + c(client); + return true; + } + return false; + }; + return new TPromise((c, e) => { + if (!getClientFn(clientId, c)) { + let disposable = this.onClientAdded.event(() => { + if (getClientFn(clientId, c)) { + disposable.dispose(); + } + }); + } + }); + } + getChannel(channelName: string, router: IClientRouter): T { const call = (command: string, arg: any) => { const id = router.routeCall(command, arg); - const client = this.ipcClients[id]; - - if (!client) { - return TPromise.wrapError('Unknown client'); - } - - return client.getChannel(channelName) - .call(command, arg); + return this.getClient(id).then(client => client.getChannel(channelName).call(command, arg)); }; - return { call } as T; } + + dispose() { + this.ipcClients = null; + this.onClientAdded.dispose(); + } } // TODO@joao: move multi channel implementation down to ipc @@ -147,6 +166,8 @@ export class Server implements IChannelServer, IRoutingChannelClient, IDisposabl } dispose(): void { + this.router.dispose(); + this.router = null; this.channels = null; this.server.close(); this.server = null;