diff --git a/packages/process/src/node/process-manager.ts b/packages/process/src/node/process-manager.ts index 91aad5ed56b89..5d191adddb394 100644 --- a/packages/process/src/node/process-manager.ts +++ b/packages/process/src/node/process-manager.ts @@ -42,7 +42,6 @@ export class ProcessManager implements BackendApplicationContribution { register(process: Process): number { const id = this.id; this.processes.set(id, process); - process.onExit(() => this.unregister(process)); process.onError(() => this.unregister(process)); this.id++; return id; @@ -54,7 +53,7 @@ export class ProcessManager implements BackendApplicationContribution { * * @param process the process to unregister from this process manager. */ - protected unregister(process: Process): void { + public unregister(process: Process): void { const processLabel = this.getProcessLabel(process); this.logger.debug(`Unregistering process. ${processLabel}`); if (!process.killed) { diff --git a/packages/process/src/node/terminal-process.ts b/packages/process/src/node/terminal-process.ts index 0aeb3c8a2c246..177733240faaf 100644 --- a/packages/process/src/node/terminal-process.ts +++ b/packages/process/src/node/terminal-process.ts @@ -102,9 +102,10 @@ export class TerminalProcess extends Process { // signal parameter will hold the signal number and code should // be ignored. if (signal === undefined || signal === 0) { - this.emitOnExit(code, undefined); + this.emitOnExit(code, undefined); // check if long task skip this } else { this.emitOnExit(undefined, signame(signal)); + this.unregisterProcess(); } process.nextTick(() => { if (signal === undefined || signal === 0) { @@ -168,6 +169,10 @@ export class TerminalProcess extends Process { } } + unregisterProcess(): void { + this.processManager.unregister(this); + } + resize(cols: number, rows: number): void { this.checkTerminal(); this.terminal!.resize(cols, rows); diff --git a/packages/terminal/src/browser/terminal-widget-impl.ts b/packages/terminal/src/browser/terminal-widget-impl.ts index 162fe01deebc2..b68dca05fed98 100644 --- a/packages/terminal/src/browser/terminal-widget-impl.ts +++ b/packages/terminal/src/browser/terminal-widget-impl.ts @@ -380,6 +380,10 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget protected async attachTerminal(id: number): Promise { const terminalId = await this.shellTerminalServer.attach(id); if (IBaseTerminalServer.validateId(terminalId)) { + const isProcessKilled = await this.shellTerminalServer.isProcessKilled(this.terminalId); + if (isProcessKilled) { + this.shellTerminalServer.unregisterProcess(this.terminalId); + } return terminalId; } this.logger.warn(`Failed attaching to terminal id ${id}, the terminal is most likely gone. Starting up a new terminal instead.`); diff --git a/packages/terminal/src/common/base-terminal-protocol.ts b/packages/terminal/src/common/base-terminal-protocol.ts index 7a25014a31d05..ac3539d28e325 100644 --- a/packages/terminal/src/common/base-terminal-protocol.ts +++ b/packages/terminal/src/common/base-terminal-protocol.ts @@ -29,9 +29,11 @@ export interface IBaseTerminalServer extends JsonRpcServer getProcessId(id: number): Promise; getProcessInfo(id: number): Promise; getCwdURI(id: number): Promise; + isProcessKilled(id: number): Promise resize(id: number, cols: number, rows: number): Promise; attach(id: number): Promise; close(id: number): Promise; + unregisterProcess(id: number): Promise; getDefaultShell(): Promise; /** @@ -171,7 +173,7 @@ export interface MergedEnvironmentVariableCollection { /** * Applies this collection to a process environment. */ - applyToProcessEnvironment(env: { [key: string]: string | null } ): void; + applyToProcessEnvironment(env: { [key: string]: string | null }): void; } export interface SerializableExtensionEnvironmentVariableCollection { diff --git a/packages/terminal/src/node/base-terminal-server.ts b/packages/terminal/src/node/base-terminal-server.ts index 57f31cd139dd6..1c58f0c02ab46 100644 --- a/packages/terminal/src/node/base-terminal-server.ts +++ b/packages/terminal/src/node/base-terminal-server.ts @@ -87,6 +87,14 @@ export abstract class BaseTerminalServer implements IBaseTerminalServer { }; } + async isProcessKilled(id: number): Promise { + const terminal = this.processManager.get(id); + if (terminal instanceof TerminalProcess) { + return terminal.killed; + } + return false; + } + async getCwdURI(id: number): Promise { const terminal = this.processManager.get(id); if (!(terminal instanceof TerminalProcess)) { @@ -103,6 +111,14 @@ export abstract class BaseTerminalServer implements IBaseTerminalServer { } } + async unregisterProcess(id: number): Promise { + const term = this.processManager.get(id); + + if (term instanceof TerminalProcess) { + term.unregisterProcess(); + } + } + async getDefaultShell(): Promise { return ShellProcess.getShellExecutablePath(); }