diff --git a/src/vs/platform/remote/common/tunnel.ts b/src/vs/platform/remote/common/tunnel.ts index eea0aacc10a..b409a1d9b62 100644 --- a/src/vs/platform/remote/common/tunnel.ts +++ b/src/vs/platform/remote/common/tunnel.ts @@ -17,7 +17,7 @@ export interface RemoteTunnel { readonly tunnelRemoteHost: string; readonly tunnelLocalPort?: number; readonly localAddress: string; - dispose(silent?: boolean): void; + dispose(silent?: boolean): Promise; } export interface TunnelOptions { @@ -119,10 +119,10 @@ export abstract class AbstractTunnelService implements ITunnelService { }); } - dispose(): void { + async dispose(): Promise { for (const portMap of this._tunnels.values()) { for (const { value } of portMap.values()) { - value.then(tunnel => tunnel?.dispose()); + await value.then(tunnel => tunnel?.dispose()); } portMap.clear(); } @@ -163,13 +163,13 @@ export abstract class AbstractTunnelService implements ITunnelService { tunnelRemoteHost: tunnel.tunnelRemoteHost, tunnelLocalPort: tunnel.tunnelLocalPort, localAddress: tunnel.localAddress, - dispose: () => { + dispose: async () => { const existingHost = this._tunnels.get(tunnel.tunnelRemoteHost); if (existingHost) { const existing = existingHost.get(tunnel.tunnelRemotePort); if (existing) { existing.refcount--; - this.tryDisposeTunnel(tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort, existing); + await this.tryDisposeTunnel(tunnel.tunnelRemoteHost, tunnel.tunnelRemotePort, existing); } } } @@ -178,9 +178,9 @@ export abstract class AbstractTunnelService implements ITunnelService { private async tryDisposeTunnel(remoteHost: string, remotePort: number, tunnel: { refcount: number, readonly value: Promise }): Promise { if (tunnel.refcount <= 0) { - const disposePromise: Promise = tunnel.value.then(tunnel => { + const disposePromise: Promise = tunnel.value.then(async (tunnel) => { if (tunnel) { - tunnel.dispose(true); + await tunnel.dispose(true); this._onTunnelClosed.fire({ host: tunnel.tunnelRemoteHost, port: tunnel.tunnelRemotePort }); } }); diff --git a/src/vs/platform/remote/node/tunnelService.ts b/src/vs/platform/remote/node/tunnelService.ts index e73c5752952..b48b54838d0 100644 --- a/src/vs/platform/remote/node/tunnelService.ts +++ b/src/vs/platform/remote/node/tunnelService.ts @@ -57,7 +57,7 @@ class NodeRemoteTunnel extends Disposable implements RemoteTunnel { this.tunnelRemoteHost = tunnelRemoteHost; } - public dispose(): void { + public async dispose(): Promise { super.dispose(); this._server.removeListener('listening', this._listeningListener); this._server.removeListener('connection', this._connectionListener); diff --git a/src/vs/platform/webview/common/webviewPortMapping.ts b/src/vs/platform/webview/common/webviewPortMapping.ts index 8809d667143..4e9c229762f 100644 --- a/src/vs/platform/webview/common/webviewPortMapping.ts +++ b/src/vs/platform/webview/common/webviewPortMapping.ts @@ -60,9 +60,9 @@ export class WebviewPortMappingManager implements IDisposable { return undefined; } - dispose() { + async dispose() { for (const tunnel of this._tunnels.values()) { - tunnel.dispose(); + await tunnel.dispose(); } this._tunnels.clear(); } diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 6ff3a5d563c..7a8667537a3 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -189,7 +189,7 @@ declare module 'vscode' { export interface Tunnel extends TunnelDescription { // Implementers of Tunnel should fire onDidDispose when dispose is called. onDidDispose: Event; - dispose(): void; + dispose(): void | Thenable; } /** diff --git a/src/vs/workbench/api/browser/mainThreadTunnelService.ts b/src/vs/workbench/api/browser/mainThreadTunnelService.ts index 8261133728d..97e31283b67 100644 --- a/src/vs/workbench/api/browser/mainThreadTunnelService.ts +++ b/src/vs/workbench/api/browser/mainThreadTunnelService.ts @@ -66,8 +66,8 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun tunnelRemoteHost: tunnel.remoteAddress.host, localAddress: typeof tunnel.localAddress === 'string' ? tunnel.localAddress : makeAddress(tunnel.localAddress.host, tunnel.localAddress.port), tunnelLocalPort: typeof tunnel.localAddress !== 'string' ? tunnel.localAddress.port : undefined, - dispose: (silent?: boolean) => { - this._proxy.$closeTunnel({ host: tunnel.remoteAddress.host, port: tunnel.remoteAddress.port }, silent); + dispose: async (silent?: boolean) => { + return this._proxy.$closeTunnel({ host: tunnel.remoteAddress.host, port: tunnel.remoteAddress.port }, silent); } }; }); diff --git a/src/vs/workbench/api/node/extHostTunnelService.ts b/src/vs/workbench/api/node/extHostTunnelService.ts index 035217d4efb..2cd5c9ecc0e 100644 --- a/src/vs/workbench/api/node/extHostTunnelService.ts +++ b/src/vs/workbench/api/node/extHostTunnelService.ts @@ -30,11 +30,11 @@ class ExtensionTunnel implements vscode.Tunnel { constructor( public readonly remoteAddress: { port: number, host: string }, public readonly localAddress: { port: number, host: string } | string, - private readonly _dispose: () => void) { } + private readonly _dispose: () => Promise) { } - dispose(): void { + dispose(): Promise { this._onDispose.fire(); - this._dispose(); + return this._dispose(); } } @@ -212,7 +212,7 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe if (silent) { hostMap.get(remote.port)!.disposeListener.dispose(); } - hostMap.get(remote.port)!.tunnel.dispose(); + await hostMap.get(remote.port)!.tunnel.dispose(); hostMap.delete(remote.port); } } diff --git a/src/vs/workbench/contrib/remote/common/tunnelFactory.ts b/src/vs/workbench/contrib/remote/common/tunnelFactory.ts index 6da6a274562..b3c0f17c8b4 100644 --- a/src/vs/workbench/contrib/remote/common/tunnelFactory.ts +++ b/src/vs/workbench/contrib/remote/common/tunnelFactory.ts @@ -36,7 +36,7 @@ export class TunnelFactoryContribution extends Disposable implements IWorkbenchC // The tunnel factory may give us an inaccessible local address. // To make sure this doesn't happen, resolve the uri immediately. localAddress: (await openerService.resolveExternalUri(URI.parse(localAddress))).resolved.toString(), - dispose: tunnel.dispose + dispose: async () => { await tunnel.dispose; } }; resolve(remoteTunnel); }); diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index f009cb06cc2..53e3c80ca24 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -73,7 +73,7 @@ export interface TunnelCreationOptions { elevationRequired?: boolean; } -interface ITunnel extends IDisposable { +interface ITunnel { remoteAddress: { port: number, host: string }; /** @@ -85,6 +85,8 @@ interface ITunnel extends IDisposable { * Implementers of Tunnel should fire onDidDispose when dispose is called. */ onDidDispose: Event; + + dispose(): Promise | void; } interface IShowPortCandidate {