fix(interactive): clean up leaked SIGINT and extension selector listeners (#2172)
- Wrap handleCtrlZ() suspend logic in try-catch so the SIGINT listener is removed if process.kill() or ui.stop() throws - Dispose previous extension selector in showExtensionSelector() before creating a new one, preventing promise leaks on rapid calls
This commit is contained in:
parent
eb48a7cdde
commit
a9667209ef
1 changed files with 24 additions and 11 deletions
|
|
@ -1519,6 +1519,13 @@ export class InteractiveMode {
|
|||
options: string[],
|
||||
opts?: ExtensionUIDialogOptions,
|
||||
): Promise<string | undefined> {
|
||||
// If a previous selector is still active, dispose it before creating a
|
||||
// new one. This avoids leaking the previous promise and DOM state when
|
||||
// showExtensionSelector is called rapidly.
|
||||
if (this.extensionSelector) {
|
||||
this.hideExtensionSelector();
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
if (opts?.signal?.aborted) {
|
||||
resolve(undefined);
|
||||
|
|
@ -2331,18 +2338,24 @@ export class InteractiveMode {
|
|||
const ignoreSigint = () => {};
|
||||
process.on("SIGINT", ignoreSigint);
|
||||
|
||||
// Set up handler to restore TUI when resumed
|
||||
process.once("SIGCONT", () => {
|
||||
try {
|
||||
// Set up handler to restore TUI when resumed
|
||||
process.once("SIGCONT", () => {
|
||||
process.removeListener("SIGINT", ignoreSigint);
|
||||
this.ui.start();
|
||||
this.ui.requestRender(true);
|
||||
});
|
||||
|
||||
// Stop the TUI (restore terminal to normal mode)
|
||||
this.ui.stop();
|
||||
|
||||
// Send SIGTSTP to process group (pid=0 means all processes in group)
|
||||
process.kill(0, "SIGTSTP");
|
||||
} catch {
|
||||
// If suspend fails (e.g. SIGTSTP not supported), ensure the
|
||||
// SIGINT listener doesn't leak.
|
||||
process.removeListener("SIGINT", ignoreSigint);
|
||||
this.ui.start();
|
||||
this.ui.requestRender(true);
|
||||
});
|
||||
|
||||
// Stop the TUI (restore terminal to normal mode)
|
||||
this.ui.stop();
|
||||
|
||||
// Send SIGTSTP to process group (pid=0 means all processes in group)
|
||||
process.kill(0, "SIGTSTP");
|
||||
}
|
||||
}
|
||||
|
||||
private async handleFollowUp(): Promise<void> {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue