Skip to content

Commit 6b53305

Browse files
authored
Merge pull request microsoft#185882 from microsoft/tyriar/185254
Restart pty host connection correctly after restart
2 parents b34f54c + 92921a0 commit 6b53305

File tree

3 files changed

+18
-11
lines changed

3 files changed

+18
-11
lines changed

src/vs/workbench/contrib/terminal/browser/baseTerminalBackend.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export abstract class BaseTerminalBackend extends Disposable {
4141

4242
let unresponsiveStatusBarEntry: IStatusbarEntry;
4343
let statusBarAccessor: IStatusbarEntryAccessor;
44+
let hasStarted = false;
4445

4546
// Attach pty host listeners
4647
if (this._ptyHostController.onPtyHostExit) {
@@ -50,7 +51,12 @@ export abstract class BaseTerminalBackend extends Disposable {
5051
}
5152
if (this._ptyHostController.onPtyHostStart) {
5253
this._register(this._ptyHostController.onPtyHostStart(() => {
53-
this._onPtyHostRestart.fire();
54+
this._logService.debug(`The terminal's pty host process is starting`);
55+
// Only fire the event on the 2nd
56+
if (hasStarted) {
57+
this._onPtyHostRestart.fire();
58+
}
59+
hasStarted = true;
5460
statusBarAccessor?.dispose();
5561
this._isPtyHostUnresponsive = false;
5662
}));

src/vs/workbench/contrib/terminal/browser/terminalInstance.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,12 +1515,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
15151515
this._isExiting = true;
15161516

15171517
await this._flushXtermData();
1518-
this._logService.debug(`Terminal process exit (instanceId: ${this.instanceId}) with code ${this._exitCode}`);
15191518

15201519
this._exitCode = parsedExitResult?.code;
15211520
const exitMessage = parsedExitResult?.message;
15221521

1523-
this._logService.debug(`Terminal process exit (instanceId: ${this.instanceId}) state ${this._processManager.processState}`);
1522+
this._logService.debug('Terminal process exit', 'instanceId', this.instanceId, 'code', this._exitCode, 'processState', this._processManager.processState);
15241523

15251524
// Only trigger wait on exit when the exit was *not* triggered by the
15261525
// user (via the `workbench.action.terminal.kill` command).

src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalBackend.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { Emitter } from 'vs/base/common/event';
6+
import { Emitter, Event } from 'vs/base/common/event';
77
import { IProcessEnvironment, isMacintosh, isWindows, OperatingSystem } from 'vs/base/common/platform';
88
import { withNullAsUndefined } from 'vs/base/common/types';
99
import { URI } from 'vs/base/common/uri';
@@ -51,8 +51,7 @@ export class LocalTerminalBackendContribution implements IWorkbenchContribution
5151
class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBackend {
5252
readonly remoteAuthority = undefined;
5353

54-
private readonly _proxy: IPtyService;
55-
private readonly _clientEventually: DeferredPromise<MessagePortClient> = new DeferredPromise();
54+
private _proxy!: IPtyService;
5655
private readonly _ptys: Map<number, LocalPty> = new Map();
5756

5857
private readonly _whenConnected = new DeferredPromise<void>();
@@ -83,12 +82,15 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke
8382
) {
8483
super(_localPtyService, logService, historyService, _configurationResolverService, statusBarService, workspaceContextService);
8584

86-
this._proxy = ProxyChannel.toService<IPtyService>(getDelayedChannel(this._clientEventually.p.then(client => client.getChannel(TerminalIpcChannels.PtyHostWindow))));
87-
88-
this._connectToDirectProxy();
85+
this._register(Event.runAndSubscribe(this.onPtyHostRestart, () => {
86+
this._logService.debug('Starting pty host');
87+
const clientEventually = new DeferredPromise<MessagePortClient>();
88+
this._proxy = ProxyChannel.toService<IPtyService>(getDelayedChannel(clientEventually.p.then(client => client.getChannel(TerminalIpcChannels.PtyHostWindow))));
89+
this._connectToDirectProxy(clientEventually);
90+
}));
8991
}
9092

91-
private async _connectToDirectProxy(): Promise<void> {
93+
private async _connectToDirectProxy(clientEventually: DeferredPromise<MessagePortClient>): Promise<void> {
9294
// The pty host should not get launched until the first window restored phase
9395
await this._lifecycleService.when(LifecyclePhase.Restored);
9496

@@ -102,7 +104,7 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke
102104
// used for pty host management messages, it would make sense in the future to use a
103105
// separate interface/service for this one.
104106
const client = new MessagePortClient(port, `window:${this._environmentService.window.id}`);
105-
this._clientEventually.complete(client);
107+
clientEventually.complete(client);
106108

107109
// Attach process listeners
108110
this._proxy.onProcessData(e => this._ptys.get(e.id)?.handleData(e.event));

0 commit comments

Comments
 (0)