Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug with hanged pseudoterminal #84181

Merged
merged 10 commits into from Nov 19, 2019
24 changes: 14 additions & 10 deletions src/vs/workbench/api/common/extHostTerminalService.ts
Expand Up @@ -288,6 +288,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
protected _activeTerminal: ExtHostTerminal | undefined;
protected _terminals: ExtHostTerminal[] = [];
protected _terminalProcesses: { [id: number]: ITerminalChildProcess } = {};
protected _extensionTerminalAwaitingStart: { [id: number]: { initialDimensions: ITerminalDimensionsDto | undefined } | undefined } = {};
protected _getTerminalPromises: { [id: number]: Promise<ExtHostTerminal> } = {};

public get activeTerminal(): ExtHostTerminal | undefined { return this._activeTerminal; }
Expand Down Expand Up @@ -462,17 +463,13 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
}
await openPromise;

// Processes should be initialized here for normal virtual process terminals, however for
// tasks they are responsible for attaching the virtual process to a terminal so this
// function may be called before tasks is able to attach to the terminal.
let retries = 5;
while (retries-- > 0) {
if (this._terminalProcesses[id]) {
(this._terminalProcesses[id] as ExtHostPseudoterminal).startSendingEvents(initialDimensions);
return;
}
await timeout(50);
if (this._terminalProcesses[id]) {
(this._terminalProcesses[id] as ExtHostPseudoterminal).startSendingEvents(initialDimensions);
} else {
// Defer startSendingEvents call to when _setupExtHostProcessListeners is called
this._extensionTerminalAwaitingStart[id] = { initialDimensions };
}

}

protected _setupExtHostProcessListeners(id: number, p: ITerminalChildProcess): void {
Expand All @@ -487,6 +484,12 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
p.onProcessOverrideDimensions(e => this._proxy.$sendOverrideDimensions(id, e));
}
this._terminalProcesses[id] = p;

const awaitingStart = this._extensionTerminalAwaitingStart[id];
if (awaitingStart && p instanceof ExtHostPseudoterminal) {
p.startSendingEvents(awaitingStart.initialDimensions);
delete this._extensionTerminalAwaitingStart[id];
}
}

public $acceptProcessInput(id: number, data: string): void {
Expand Down Expand Up @@ -525,6 +528,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ

// Remove process reference
delete this._terminalProcesses[id];
delete this._extensionTerminalAwaitingStart[id];

// Send exit event to main side
this._proxy.$sendProcessExit(id, exitCode);
Expand Down