Integration tests: terminal throws exceptions (fix #90046)

This commit is contained in:
Benjamin Pasero
2020-02-13 11:31:52 +01:00
parent a56618ad8f
commit 54d57f552f

View File

@@ -13,6 +13,7 @@ import { ITerminalChildProcess, ITerminalDimensions, EXT_HOST_CREATION_DELAY } f
import { timeout } from 'vs/base/common/async';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { TerminalDataBufferer } from 'vs/workbench/contrib/terminal/common/terminalDataBuffering';
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
export interface IExtHostTerminalService extends ExtHostTerminalServiceShape {
@@ -290,6 +291,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
protected _activeTerminal: ExtHostTerminal | undefined;
protected _terminals: ExtHostTerminal[] = [];
protected _terminalProcesses: { [id: number]: ITerminalChildProcess } = {};
protected _terminalProcessDisposables: { [id: number]: IDisposable } = {};
protected _extensionTerminalAwaitingStart: { [id: number]: { initialDimensions: ITerminalDimensionsDto | undefined } | undefined } = {};
protected _getTerminalPromises: { [id: number]: Promise<ExtHostTerminal> } = {};
@@ -332,7 +334,10 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
public createExtensionTerminal(options: vscode.ExtensionTerminalOptions): vscode.Terminal {
const terminal = new ExtHostTerminal(this._proxy, options, options.name);
const p = new ExtHostPseudoterminal(options.pty);
terminal.createExtensionTerminal().then(id => this._setupExtHostProcessListeners(id, p));
terminal.createExtensionTerminal().then(id => {
const disposable = this._setupExtHostProcessListeners(id, p);
this._terminalProcessDisposables[id] = disposable;
});
this._terminals.push(terminal);
return terminal;
}
@@ -343,7 +348,8 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
throw new Error(`Cannot resolve terminal with id ${id} for virtual process`);
}
const p = new ExtHostPseudoterminal(pty);
this._setupExtHostProcessListeners(id, p);
const disposable = this._setupExtHostProcessListeners(id, p);
this._terminalProcessDisposables[id] = disposable;
}
public async $acceptActiveTerminalChanged(id: number | null): Promise<void> {
@@ -474,16 +480,18 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
}
protected _setupExtHostProcessListeners(id: number, p: ITerminalChildProcess): void {
p.onProcessReady((e: { pid: number, cwd: string }) => this._proxy.$sendProcessReady(id, e.pid, e.cwd));
p.onProcessTitleChanged(title => this._proxy.$sendProcessTitle(id, title));
protected _setupExtHostProcessListeners(id: number, p: ITerminalChildProcess): IDisposable {
const disposables = new DisposableStore();
disposables.add(p.onProcessReady((e: { pid: number, cwd: string }) => this._proxy.$sendProcessReady(id, e.pid, e.cwd)));
disposables.add(p.onProcessTitleChanged(title => this._proxy.$sendProcessTitle(id, title)));
// Buffer data events to reduce the amount of messages going to the renderer
this._bufferer.startBuffering(id, p.onProcessData);
p.onProcessExit(exitCode => this._onProcessExit(id, exitCode));
disposables.add(p.onProcessExit(exitCode => this._onProcessExit(id, exitCode)));
if (p.onProcessOverrideDimensions) {
p.onProcessOverrideDimensions(e => this._proxy.$sendOverrideDimensions(id, e));
disposables.add(p.onProcessOverrideDimensions(e => this._proxy.$sendOverrideDimensions(id, e)));
}
this._terminalProcesses[id] = p;
@@ -492,6 +500,8 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
p.startSendingEvents(awaitingStart.initialDimensions);
delete this._extensionTerminalAwaitingStart[id];
}
return disposables;
}
public $acceptProcessInput(id: number, data: string): void {
@@ -532,6 +542,13 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
delete this._terminalProcesses[id];
delete this._extensionTerminalAwaitingStart[id];
// Clean up process disposables
const processDiposable = this._terminalProcessDisposables[id];
if (processDiposable) {
processDiposable.dispose();
delete this._terminalProcessDisposables[id];
}
// Send exit event to main side
this._proxy.$sendProcessExit(id, exitCode);
}