Skip to content

Commit 2fbfcb1

Browse files
committed
Call ctor with port so proxy is non-undefined
1 parent 7f832cc commit 2fbfcb1

File tree

3 files changed

+47
-46
lines changed

3 files changed

+47
-46
lines changed

src/vs/platform/terminal/common/terminal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ export interface IPtyHostController {
273273
readonly onPtyHostResponsive?: Event<void>;
274274
readonly onPtyHostRequestResolveVariables?: Event<IRequestResolveVariablesEvent>;
275275

276-
restartPtyHost?(): Promise<void>;
276+
restartPtyHost?(): void;
277277
acceptPtyHostResolvedVariables?(requestId: number, resolved: string[]): Promise<void>;
278278
}
279279

src/vs/platform/terminal/node/ptyHostService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,9 @@ export class PtyHostService extends Disposable implements IPtyService {
312312
}
313313

314314
async restartPtyHost(): Promise<void> {
315-
this._isResponsive = true;
316315
this._disposePtyHost();
317-
[this._connection, this._proxy] = await this._startPtyHost();
316+
this._isResponsive = true;
317+
[this._connection, this._proxy] = this._startPtyHost();
318318
}
319319

320320
private _disposePtyHost(): void {

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

Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,34 @@ import { mark } from 'vs/base/common/performance';
3939
export class LocalTerminalBackendContribution implements IWorkbenchContribution {
4040
constructor(
4141
@IInstantiationService instantiationService: IInstantiationService,
42+
@ILogService logService: ILogService,
4243
@ITerminalInstanceService terminalInstanceService: ITerminalInstanceService
4344
) {
44-
const backend = instantiationService.createInstance(LocalTerminalBackend, undefined);
45-
Registry.as<ITerminalBackendRegistry>(TerminalExtensions.Backend).registerTerminalBackend(backend);
46-
terminalInstanceService.didRegisterBackend(backend.remoteAuthority);
45+
mark('code/willConnectPtyHost');
46+
logService.trace('Renderer->PtyHost#connect: before acquirePort');
47+
acquirePort('vscode:createPtyHostMessageChannel', 'vscode:createPtyHostMessageChannelResult').then(port => {
48+
mark('code/didConnectPtyHost');
49+
logService.trace('Renderer->PtyHost#connect: connection established');
50+
51+
const backend = instantiationService.createInstance(LocalTerminalBackend, port);
52+
Registry.as<ITerminalBackendRegistry>(TerminalExtensions.Backend).registerTerminalBackend(backend);
53+
terminalInstanceService.didRegisterBackend(backend.remoteAuthority);
54+
});
4755
}
4856
}
4957

5058
class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBackend {
59+
readonly remoteAuthority = undefined;
60+
5161
private readonly _ptys: Map<number, LocalPty> = new Map();
5262

53-
private _ptyHostDirectProxy: IPtyService | undefined;
63+
private _ptyHostDirectProxy: IPtyService;
5464

5565
private readonly _onDidRequestDetach = this._register(new Emitter<{ requestId: number; workspaceId: string; instanceId: number }>());
5666
readonly onDidRequestDetach = this._onDidRequestDetach.event;
5767

5868
constructor(
59-
readonly remoteAuthority: string | undefined,
69+
port: MessagePort,
6070
@IInstantiationService private readonly _instantiationService: IInstantiationService,
6171
@IWorkspaceContextService workspaceContextService: IWorkspaceContextService,
6272
@ILogService logService: ILogService,
@@ -76,90 +86,81 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke
7686
) {
7787
super(_localPtyService, logService, notificationService, historyService, _configurationResolverService, workspaceContextService);
7888

79-
// TODO: If we connect async like this, there may be a race condition where messages go missing before the message port is established
80-
this._start();
81-
}
82-
83-
private async _start() {
84-
85-
// TODO: Use the direct connection
86-
mark('code/willConnectPtyHost');
87-
this._logService.trace('Renderer->PtyHost#connect: before acquirePort');
88-
const port = await acquirePort('vscode:createPtyHostMessageChannel', 'vscode:createPtyHostMessageChannelResult');
89-
mark('code/didConnectPtyHost');
90-
this._logService.trace('Renderer->PtyHost#connect: connection established');
91-
89+
// There are two connections to the pty host; one to the regular shared process
90+
// _localPtyService, and one directly via message port _ptyHostDirectProxy. The former is
91+
// used for pty host management messages, it would make sense in the future to use a
92+
// separate interface/service for this one.
9293
const client = new MessagePortClient(port, `window:${this._environmentService.window.id}`);
9394
this._ptyHostDirectProxy = ProxyChannel.toService<IPtyService>(client.getChannel(TerminalIpcChannels.PtyHostWindow));
9495

9596
// Attach process listeners
96-
this._ptyHostDirectProxy!.onProcessData(e => this._ptys.get(e.id)?.handleData(e.event));
97-
this._ptyHostDirectProxy!.onDidChangeProperty(e => this._ptys.get(e.id)?.handleDidChangeProperty(e.property));
98-
this._ptyHostDirectProxy!.onProcessExit(e => {
97+
this._ptyHostDirectProxy.onProcessData(e => this._ptys.get(e.id)?.handleData(e.event));
98+
this._ptyHostDirectProxy.onDidChangeProperty(e => this._ptys.get(e.id)?.handleDidChangeProperty(e.property));
99+
this._ptyHostDirectProxy.onProcessExit(e => {
99100
const pty = this._ptys.get(e.id);
100101
if (pty) {
101102
pty.handleExit(e.event);
102103
this._ptys.delete(e.id);
103104
}
104105
});
105-
this._ptyHostDirectProxy!.onProcessReady(e => this._ptys.get(e.id)?.handleReady(e.event));
106-
this._ptyHostDirectProxy!.onProcessReplay(e => this._ptys.get(e.id)?.handleReplay(e.event));
107-
this._ptyHostDirectProxy!.onProcessOrphanQuestion(e => this._ptys.get(e.id)?.handleOrphanQuestion());
108-
this._ptyHostDirectProxy!.onDidRequestDetach(e => this._onDidRequestDetach.fire(e));
106+
this._ptyHostDirectProxy.onProcessReady(e => this._ptys.get(e.id)?.handleReady(e.event));
107+
this._ptyHostDirectProxy.onProcessReplay(e => this._ptys.get(e.id)?.handleReplay(e.event));
108+
this._ptyHostDirectProxy.onProcessOrphanQuestion(e => this._ptys.get(e.id)?.handleOrphanQuestion());
109+
this._ptyHostDirectProxy.onDidRequestDetach(e => this._onDidRequestDetach.fire(e));
109110

110111
// Listen for config changes
111112
const initialConfig = this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION);
112113
for (const match of Object.keys(initialConfig.autoReplies)) {
113114
// Ensure the reply is value
114115
const reply = initialConfig.autoReplies[match] as string | null;
115116
if (reply) {
116-
this._ptyHostDirectProxy!.installAutoReply(match, reply);
117+
this._ptyHostDirectProxy.installAutoReply(match, reply);
117118
}
118119
}
119120
// TODO: Could simplify update to a single call
120121
this._register(this._configurationService.onDidChangeConfiguration(async e => {
121122
if (e.affectsConfiguration(TerminalSettingId.AutoReplies)) {
122-
this._ptyHostDirectProxy!.uninstallAllAutoReplies();
123+
this._ptyHostDirectProxy.uninstallAllAutoReplies();
123124
const config = this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION);
124125
for (const match of Object.keys(config.autoReplies)) {
125126
// Ensure the reply is value
126127
const reply = config.autoReplies[match] as string | null;
127128
if (reply) {
128-
await this._ptyHostDirectProxy!.installAutoReply(match, reply);
129+
await this._ptyHostDirectProxy.installAutoReply(match, reply);
129130
}
130131
}
131132
}
132133
}));
133134
}
134135

135136
async requestDetachInstance(workspaceId: string, instanceId: number): Promise<IProcessDetails | undefined> {
136-
return this._ptyHostDirectProxy!.requestDetachInstance(workspaceId, instanceId);
137+
return this._ptyHostDirectProxy.requestDetachInstance(workspaceId, instanceId);
137138
}
138139

139140
async acceptDetachInstanceReply(requestId: number, persistentProcessId?: number): Promise<void> {
140141
if (!persistentProcessId) {
141142
this._logService.warn('Cannot attach to feature terminals, custom pty terminals, or those without a persistentProcessId');
142143
return;
143144
}
144-
return this._ptyHostDirectProxy!.acceptDetachInstanceReply(requestId, persistentProcessId);
145+
return this._ptyHostDirectProxy.acceptDetachInstanceReply(requestId, persistentProcessId);
145146
}
146147

147148
async persistTerminalState(): Promise<void> {
148149
const ids = Array.from(this._ptys.keys());
149-
const serialized = await this._ptyHostDirectProxy!.serializeTerminalState(ids);
150+
const serialized = await this._ptyHostDirectProxy.serializeTerminalState(ids);
150151
this._storageService.store(TerminalStorageKeys.TerminalBufferState, serialized, StorageScope.WORKSPACE, StorageTarget.MACHINE);
151152
}
152153

153154
async updateTitle(id: number, title: string, titleSource: TitleEventSource): Promise<void> {
154-
await this._ptyHostDirectProxy!.updateTitle(id, title, titleSource);
155+
await this._ptyHostDirectProxy.updateTitle(id, title, titleSource);
155156
}
156157

157158
async updateIcon(id: number, userInitiated: boolean, icon: URI | { light: URI; dark: URI } | { id: string; color?: { id: string } }, color?: string): Promise<void> {
158-
await this._ptyHostDirectProxy!.updateIcon(id, userInitiated, icon, color);
159+
await this._ptyHostDirectProxy.updateIcon(id, userInitiated, icon, color);
159160
}
160161

161162
updateProperty<T extends ProcessPropertyType>(id: number, property: ProcessPropertyType, value: IProcessPropertyMap[T]): Promise<void> {
162-
return this._ptyHostDirectProxy!.updateProperty(id, property, value);
163+
return this._ptyHostDirectProxy.updateProperty(id, property, value);
163164
}
164165

165166
async createProcess(
@@ -173,15 +174,15 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke
173174
shouldPersist: boolean
174175
): Promise<ITerminalChildProcess> {
175176
const executableEnv = await this._shellEnvironmentService.getShellEnv();
176-
const id = await this._ptyHostDirectProxy!.createProcess(shellLaunchConfig, cwd, cols, rows, unicodeVersion, env, executableEnv, options, shouldPersist, this._getWorkspaceId(), this._getWorkspaceName());
177+
const id = await this._ptyHostDirectProxy.createProcess(shellLaunchConfig, cwd, cols, rows, unicodeVersion, env, executableEnv, options, shouldPersist, this._getWorkspaceId(), this._getWorkspaceName());
177178
const pty = this._instantiationService.createInstance(LocalPty, id, shouldPersist);
178179
this._ptys.set(id, pty);
179180
return pty;
180181
}
181182

182183
async attachToProcess(id: number): Promise<ITerminalChildProcess | undefined> {
183184
try {
184-
await this._ptyHostDirectProxy!.attachToProcess(id);
185+
await this._ptyHostDirectProxy.attachToProcess(id);
185186
const pty = this._instantiationService.createInstance(LocalPty, id, true);
186187
this._ptys.set(id, pty);
187188
return pty;
@@ -193,7 +194,7 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke
193194

194195
async attachToRevivedProcess(id: number): Promise<ITerminalChildProcess | undefined> {
195196
try {
196-
const newId = await this._ptyHostDirectProxy!.getRevivedPtyNewId(id) ?? id;
197+
const newId = await this._ptyHostDirectProxy.getRevivedPtyNewId(id) ?? id;
197198
return await this.attachToProcess(newId);
198199
} catch (e) {
199200
this._logService.warn(`Couldn't attach to process ${e.message}`);
@@ -202,15 +203,15 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke
202203
}
203204

204205
async listProcesses(): Promise<IProcessDetails[]> {
205-
return this._ptyHostDirectProxy!.listProcesses();
206+
return this._ptyHostDirectProxy.listProcesses();
206207
}
207208

208209
async reduceConnectionGraceTime(): Promise<void> {
209-
this._ptyHostDirectProxy!.reduceConnectionGraceTime();
210+
this._ptyHostDirectProxy.reduceConnectionGraceTime();
210211
}
211212

212213
async getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string> {
213-
return this._ptyHostDirectProxy!.getDefaultSystemShell(osOverride);
214+
return this._ptyHostDirectProxy.getDefaultSystemShell(osOverride);
214215
}
215216

216217
async getProfiles(profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean) {
@@ -219,23 +220,23 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke
219220
}
220221

221222
async getEnvironment(): Promise<IProcessEnvironment> {
222-
return this._ptyHostDirectProxy!.getEnvironment();
223+
return this._ptyHostDirectProxy.getEnvironment();
223224
}
224225

225226
async getShellEnvironment(): Promise<IProcessEnvironment> {
226227
return this._shellEnvironmentService.getShellEnv();
227228
}
228229

229230
async getWslPath(original: string, direction: 'unix-to-win' | 'win-to-unix'): Promise<string> {
230-
return this._ptyHostDirectProxy!.getWslPath(original, direction);
231+
return this._ptyHostDirectProxy.getWslPath(original, direction);
231232
}
232233

233234
async setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): Promise<void> {
234235
const args: ISetTerminalLayoutInfoArgs = {
235236
workspaceId: this._getWorkspaceId(),
236237
tabs: layoutInfo ? layoutInfo.tabs : []
237238
};
238-
await this._ptyHostDirectProxy!.setTerminalLayoutInfo(args);
239+
await this._ptyHostDirectProxy.setTerminalLayoutInfo(args);
239240
// Store in the storage service as well to be used when reviving processes as normally this
240241
// is stored in memory on the pty host
241242
this._storageService.store(TerminalStorageKeys.TerminalLayoutInfo, JSON.stringify(args), StorageScope.WORKSPACE, StorageTarget.MACHINE);

0 commit comments

Comments
 (0)