@@ -46,6 +46,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
4646import { TaskRunResult , DebugTaskRunner } from 'vs/workbench/contrib/debug/browser/debugTaskRunner' ;
4747import { IActivityService , NumberBadge } from 'vs/workbench/services/activity/common/activity' ;
4848import { IViewsService } from 'vs/workbench/common/views' ;
49+ import { generateUuid } from 'vs/base/common/uuid' ;
4950
5051const DEBUG_BREAKPOINTS_KEY = 'debug.breakpoint' ;
5152const DEBUG_FUNCTION_BREAKPOINTS_KEY = 'debug.functionbreakpoint' ;
@@ -73,7 +74,7 @@ export class DebugService implements IDebugService {
7374 private breakpointsToSendOnResourceSaved : Set < string > ;
7475 private initializing = false ;
7576 private previousState : State | undefined ;
76- private initCancellationToken : CancellationTokenSource | undefined ;
77+ private sessionCancellationTokens = new Map < string , CancellationTokenSource > ( ) ;
7778 private activity : IDisposable | undefined ;
7879
7980 constructor (
@@ -206,24 +207,33 @@ export class DebugService implements IDebugService {
206207 return this . initializing ? State . Initializing : State . Inactive ;
207208 }
208209
209- private startInitializingState ( ) {
210+ private startInitializingState ( ) : void {
210211 if ( ! this . initializing ) {
211212 this . initializing = true ;
212213 this . onStateChange ( ) ;
213214 }
214215 }
215216
216- private endInitializingState ( ) {
217- if ( this . initCancellationToken ) {
218- this . initCancellationToken . cancel ( ) ;
219- this . initCancellationToken = undefined ;
220- }
217+ private endInitializingState ( ) : void {
221218 if ( this . initializing ) {
222219 this . initializing = false ;
223220 this . onStateChange ( ) ;
224221 }
225222 }
226223
224+ private cancelTokens ( id : string | undefined ) : void {
225+ if ( id ) {
226+ const token = this . sessionCancellationTokens . get ( id ) ;
227+ if ( token ) {
228+ token . cancel ( ) ;
229+ this . sessionCancellationTokens . delete ( id ) ;
230+ }
231+ } else {
232+ this . sessionCancellationTokens . forEach ( t => t . cancel ( ) ) ;
233+ this . sessionCancellationTokens . clear ( ) ;
234+ }
235+ }
236+
227237 private onStateChange ( ) : void {
228238 const state = this . state ;
229239 if ( this . previousState !== state ) {
@@ -380,8 +390,11 @@ export class DebugService implements IDebugService {
380390 }
381391 }
382392
383- this . initCancellationToken = new CancellationTokenSource ( ) ;
384- const configByProviders = await this . configurationManager . resolveConfigurationByProviders ( launch && launch . workspace ? launch . workspace . uri : undefined , type , config ! , this . initCancellationToken . token ) ;
393+ const initCancellationToken = new CancellationTokenSource ( ) ;
394+ const sessionId = generateUuid ( ) ;
395+ this . sessionCancellationTokens . set ( sessionId , initCancellationToken ) ;
396+
397+ const configByProviders = await this . configurationManager . resolveConfigurationByProviders ( launch && launch . workspace ? launch . workspace . uri : undefined , type , config ! , initCancellationToken . token ) ;
385398 // a falsy config indicates an aborted launch
386399 if ( configByProviders && configByProviders . type ) {
387400 try {
@@ -391,15 +404,15 @@ export class DebugService implements IDebugService {
391404 return false ;
392405 }
393406
394- if ( ! this . initCancellationToken ) {
407+ if ( initCancellationToken . token . isCancellationRequested ) {
395408 // User cancelled, silently return
396409 return false ;
397410 }
398411
399- const cfg = await this . configurationManager . resolveDebugConfigurationWithSubstitutedVariables ( launch && launch . workspace ? launch . workspace . uri : undefined , type , resolvedConfig , this . initCancellationToken . token ) ;
412+ const cfg = await this . configurationManager . resolveDebugConfigurationWithSubstitutedVariables ( launch && launch . workspace ? launch . workspace . uri : undefined , type , resolvedConfig , initCancellationToken . token ) ;
400413 if ( ! cfg ) {
401- if ( launch && type && cfg === null && this . initCancellationToken ) { // show launch.json only for "config" being "null".
402- await launch . openConfigFile ( false , true , type , this . initCancellationToken . token ) ;
414+ if ( launch && type && cfg === null && ! initCancellationToken . token . isCancellationRequested ) { // show launch.json only for "config" being "null".
415+ await launch . openConfigFile ( false , true , type , initCancellationToken . token ) ;
403416 }
404417 return false ;
405418 }
@@ -423,7 +436,7 @@ export class DebugService implements IDebugService {
423436 const workspace = launch ?. workspace || this . contextService . getWorkspace ( ) ;
424437 const taskResult = await this . taskRunner . runTaskAndCheckErrors ( workspace , resolvedConfig . preLaunchTask , ( msg , actions ) => this . showError ( msg , actions ) ) ;
425438 if ( taskResult === TaskRunResult . Success ) {
426- return this . doCreateSession ( launch ?. workspace , { resolved : resolvedConfig , unresolved : unresolvedConfig } , options ) ;
439+ return this . doCreateSession ( sessionId , launch ?. workspace , { resolved : resolvedConfig , unresolved : unresolvedConfig } , options ) ;
427440 }
428441 return false ;
429442 } catch ( err ) {
@@ -432,16 +445,16 @@ export class DebugService implements IDebugService {
432445 } else if ( this . contextService . getWorkbenchState ( ) === WorkbenchState . EMPTY ) {
433446 await this . showError ( nls . localize ( 'noFolderWorkspaceDebugError' , "The active file can not be debugged. Make sure it is saved and that you have a debug extension installed for that file type." ) ) ;
434447 }
435- if ( launch && this . initCancellationToken ) {
436- await launch . openConfigFile ( false , true , undefined , this . initCancellationToken . token ) ;
448+ if ( launch && ! initCancellationToken . token . isCancellationRequested ) {
449+ await launch . openConfigFile ( false , true , undefined , initCancellationToken . token ) ;
437450 }
438451
439452 return false ;
440453 }
441454 }
442455
443- if ( launch && type && configByProviders === null && this . initCancellationToken ) { // show launch.json only for "config" being "null".
444- await launch . openConfigFile ( false , true , type , this . initCancellationToken . token ) ;
456+ if ( launch && type && configByProviders === null && ! initCancellationToken . token . isCancellationRequested ) { // show launch.json only for "config" being "null".
457+ await launch . openConfigFile ( false , true , type , initCancellationToken . token ) ;
445458 }
446459
447460 return false ;
@@ -450,9 +463,9 @@ export class DebugService implements IDebugService {
450463 /**
451464 * instantiates the new session, initializes the session, registers session listeners and reports telemetry
452465 */
453- private async doCreateSession ( root : IWorkspaceFolder | undefined , configuration : { resolved : IConfig , unresolved : IConfig | undefined } , options ?: IDebugSessionOptions ) : Promise < boolean > {
466+ private async doCreateSession ( sessionId : string , root : IWorkspaceFolder | undefined , configuration : { resolved : IConfig , unresolved : IConfig | undefined } , options ?: IDebugSessionOptions ) : Promise < boolean > {
454467
455- const session = this . instantiationService . createInstance ( DebugSession , configuration , root , this . model , options ) ;
468+ const session = this . instantiationService . createInstance ( DebugSession , sessionId , configuration , root , this . model , options ) ;
456469 this . model . addSession ( session ) ;
457470 // register listeners as the very first thing!
458471 this . registerSessionListeners ( session ) ;
@@ -566,6 +579,7 @@ export class DebugService implements IDebugService {
566579 }
567580 }
568581 this . endInitializingState ( ) ;
582+ this . cancelTokens ( session . getId ( ) ) ;
569583 this . _onDidEndSession . fire ( session ) ;
570584
571585 const focusedSession = this . viewModel . focusedSession ;
@@ -656,12 +670,13 @@ export class DebugService implements IDebugService {
656670
657671 let resolved : IConfig | undefined | null = session . configuration ;
658672 if ( launch && needsToSubstitute && unresolved ) {
659- this . initCancellationToken = new CancellationTokenSource ( ) ;
660- const resolvedByProviders = await this . configurationManager . resolveConfigurationByProviders ( launch . workspace ? launch . workspace . uri : undefined , unresolved . type , unresolved , this . initCancellationToken . token ) ;
673+ const initCancellationToken = new CancellationTokenSource ( ) ;
674+ this . sessionCancellationTokens . set ( session . getId ( ) , initCancellationToken ) ;
675+ const resolvedByProviders = await this . configurationManager . resolveConfigurationByProviders ( launch . workspace ? launch . workspace . uri : undefined , unresolved . type , unresolved , initCancellationToken . token ) ;
661676 if ( resolvedByProviders ) {
662677 resolved = await this . substituteVariables ( launch , resolvedByProviders ) ;
663- if ( resolved && this . initCancellationToken ) {
664- resolved = await this . configurationManager . resolveDebugConfigurationWithSubstitutedVariables ( launch && launch . workspace ? launch . workspace . uri : undefined , unresolved . type , resolved , this . initCancellationToken . token ) ;
678+ if ( resolved && ! initCancellationToken . token . isCancellationRequested ) {
679+ resolved = await this . configurationManager . resolveDebugConfigurationWithSubstitutedVariables ( launch && launch . workspace ? launch . workspace . uri : undefined , unresolved . type , resolved , initCancellationToken . token ) ;
665680 }
666681 } else {
667682 resolved = resolvedByProviders ;
@@ -695,6 +710,7 @@ export class DebugService implements IDebugService {
695710 if ( sessions . length === 0 ) {
696711 this . taskRunner . cancel ( ) ;
697712 this . endInitializingState ( ) ;
713+ this . cancelTokens ( undefined ) ;
698714 }
699715
700716 return Promise . all ( sessions . map ( s => s . terminate ( ) ) ) ;
0 commit comments