@@ -309,7 +309,7 @@ export class ExtHostTerminal extends Disposable {
309309 }
310310}
311311
312- class ExtHostPseudoterminal implements ITerminalChildProcess {
312+ class ExtHostPseudoterminal extends Disposable implements ITerminalChildProcess {
313313 readonly id = 0 ;
314314 readonly shouldPersist = false ;
315315
@@ -322,7 +322,9 @@ class ExtHostPseudoterminal implements ITerminalChildProcess {
322322 private readonly _onProcessExit = new Emitter < number | undefined > ( ) ;
323323 public readonly onProcessExit : Event < number | undefined > = this . _onProcessExit . event ;
324324
325- constructor ( private readonly _pty : vscode . Pseudoterminal ) { }
325+ constructor ( private readonly _pty : vscode . Pseudoterminal ) {
326+ super ( ) ;
327+ }
326328
327329 refreshProperty < T extends ProcessPropertyType > ( property : ProcessPropertyType ) : Promise < IProcessPropertyMap [ T ] > {
328330 throw new Error ( `refreshProperty is not suppported in extension owned terminals. property: ${ property } ` ) ;
@@ -380,18 +382,18 @@ class ExtHostPseudoterminal implements ITerminalChildProcess {
380382
381383 startSendingEvents ( initialDimensions : ITerminalDimensionsDto | undefined ) : void {
382384 // Attach the listeners
383- this . _pty . onDidWrite ( e => this . _onProcessData . fire ( e ) ) ;
384- this . _pty . onDidClose ?.( ( e : number | void = undefined ) => {
385+ this . _register ( this . _pty . onDidWrite ( e => this . _onProcessData . fire ( e ) ) ) ;
386+ this . _register ( this . _pty . onDidClose ?.( ( e : number | void = undefined ) => {
385387 this . _onProcessExit . fire ( e === void 0 ? undefined : e ) ;
386- } ) ;
387- this . _pty . onDidOverrideDimensions ?.( e => {
388+ } ) ?? Disposable . None ) ;
389+ this . _register ( this . _pty . onDidOverrideDimensions ?.( e => {
388390 if ( e ) {
389391 this . _onDidChangeProperty . fire ( { type : ProcessPropertyType . OverrideDimensions , value : { cols : e . columns , rows : e . rows } } ) ;
390392 }
391- } ) ;
392- this . _pty . onDidChangeName ?.( title => {
393+ } ) ?? Disposable . None ) ;
394+ this . _register ( this . _pty . onDidChangeName ?.( title => {
393395 this . _onDidChangeProperty . fire ( { type : ProcessPropertyType . Title , value : title } ) ;
394- } ) ;
396+ } ) ?? Disposable . None ) ;
395397
396398 this . _pty . open ( initialDimensions ? initialDimensions : undefined ) ;
397399
@@ -520,8 +522,10 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
520522 const terminal = new ExtHostTerminal ( this . _proxy , generateUuid ( ) , options , options . name ) ;
521523 const p = new ExtHostPseudoterminal ( options . pty ) ;
522524 terminal . createExtensionTerminal ( options . location , internalOptions , this . _serializeParentTerminal ( options , internalOptions ) . resolvedExtHostIdentifier , asTerminalIcon ( options . iconPath ) , asTerminalColor ( options . color ) , options . shellIntegrationNonce , options . titleTemplate ) . then ( id => {
523- const disposable = this . _setupExtHostProcessListeners ( id , p ) ;
524- this . _terminalProcessDisposables [ id ] = disposable ;
525+ if ( ! this . getTerminalById ( id ) ) {
526+ return ;
527+ }
528+ this . _setupExtHostProcessListeners ( id , p ) ;
525529 } ) ;
526530 this . _terminals . push ( terminal ) ;
527531 return terminal . value ;
@@ -551,8 +555,7 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
551555 throw new Error ( `Cannot resolve terminal with id ${ id } for virtual process` ) ;
552556 }
553557 const p = new ExtHostPseudoterminal ( pty ) ;
554- const disposable = this . _setupExtHostProcessListeners ( id , p ) ;
555- this . _terminalProcessDisposables [ id ] = disposable ;
558+ this . _setupExtHostProcessListeners ( id , p ) ;
556559 }
557560
558561 public async $acceptActiveTerminalChanged ( id : number | null ) : Promise < void > {
@@ -613,6 +616,8 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
613616 }
614617
615618 public async $acceptTerminalClosed ( id : number , exitCode : number | undefined , exitReason : TerminalExitReason ) : Promise < void > {
619+ this . _cleanUpTerminalProcess ( id ) ;
620+
616621 // Release any cached terminal links and cancel in-flight link providers for this terminal
617622 this . _terminalLinkCache . delete ( id ) ;
618623 const cancellationSource = this . _terminalLinkCancellationSource . get ( id ) ;
@@ -694,23 +699,26 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
694699 return undefined ;
695700 }
696701
697- protected _setupExtHostProcessListeners ( id : number , p : ITerminalChildProcess ) : IDisposable {
702+ protected _setupExtHostProcessListeners ( id : number , p : ITerminalChildProcess ) : void {
698703 const disposables = new DisposableStore ( ) ;
704+ if ( p instanceof ExtHostPseudoterminal ) {
705+ disposables . add ( p ) ;
706+ }
699707 disposables . add ( p . onProcessReady ( e => this . _proxy . $sendProcessReady ( id , e . pid , e . cwd , e . windowsPty ) ) ) ;
700708 disposables . add ( p . onDidChangeProperty ( property => this . _proxy . $sendProcessProperty ( id , property ) ) ) ;
701709
702710 // Buffer data events to reduce the amount of messages going to the renderer
703- this . _bufferer . startBuffering ( id , p . onProcessData ) ;
711+ disposables . add ( this . _bufferer . startBuffering ( id , p . onProcessData ) ) ;
704712 disposables . add ( p . onProcessExit ( exitCode => this . _onProcessExit ( id , exitCode ) ) ) ;
705713 this . _terminalProcesses . set ( id , p ) ;
714+ this . _terminalProcessDisposables [ id ] = disposables ;
706715
707716 const awaitingStart = this . _extensionTerminalAwaitingStart [ id ] ;
708717 if ( awaitingStart && p instanceof ExtHostPseudoterminal ) {
709718 p . startSendingEvents ( awaitingStart . initialDimensions ) ;
710719 delete this . _extensionTerminalAwaitingStart [ id ] ;
711720 }
712721
713- return disposables ;
714722 }
715723
716724 public $acceptProcessAckDataEvent ( id : number , charCount : number ) : void {
@@ -980,6 +988,13 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
980988 }
981989
982990 private _onProcessExit ( id : number , exitCode : number | undefined ) : void {
991+ this . _cleanUpTerminalProcess ( id ) ;
992+
993+ // Send exit event to main side
994+ this . _proxy . $sendProcessExit ( id , exitCode ) ;
995+ }
996+
997+ private _cleanUpTerminalProcess ( id : number ) : void {
983998 this . _bufferer . stopBuffering ( id ) ;
984999
9851000 // Remove process reference
@@ -992,8 +1007,6 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I
9921007 processDiposable . dispose ( ) ;
9931008 delete this . _terminalProcessDisposables [ id ] ;
9941009 }
995- // Send exit event to main side
996- this . _proxy . $sendProcessExit ( id , exitCode ) ;
9971010 }
9981011
9991012 public getTerminalById ( id : number ) : ExtHostTerminal | null {
0 commit comments