@@ -975,76 +975,81 @@ export class DebugSession implements IDebugSession {
975
975
}
976
976
} ) ) ;
977
977
978
+ const statusQueue = new Queue < void > ( ) ;
978
979
this . rawListeners . push ( this . raw . onDidStop ( async event => {
979
- this . passFocusScheduler . cancel ( ) ;
980
- this . stoppedDetails . push ( event . body ) ;
981
- await this . fetchThreads ( event . body ) ;
982
- // If the focus for the current session is on a non-existent thread, clear the focus.
983
- const focusedThread = this . debugService . getViewModel ( ) . focusedThread ;
984
- const focusedThreadDoesNotExist = focusedThread !== undefined && focusedThread . session === this && ! this . threads . has ( focusedThread . threadId ) ;
985
- if ( focusedThreadDoesNotExist ) {
986
- this . debugService . focusStackFrame ( undefined , undefined ) ;
987
- }
988
- const thread = typeof event . body . threadId === 'number' ? this . getThread ( event . body . threadId ) : undefined ;
989
- if ( thread ) {
990
- // Call fetch call stack twice, the first only return the top stack frame.
991
- // Second retrieves the rest of the call stack. For performance reasons #25605
992
- const promises = this . model . refreshTopOfCallstack ( < Thread > thread ) ;
993
- const focus = async ( ) => {
994
- if ( focusedThreadDoesNotExist || ( ! event . body . preserveFocusHint && thread . getCallStack ( ) . length ) ) {
995
- const focusedStackFrame = this . debugService . getViewModel ( ) . focusedStackFrame ;
996
- if ( ! focusedStackFrame || focusedStackFrame . thread . session === this ) {
997
- // Only take focus if nothing is focused, or if the focus is already on the current session
998
- const preserveFocus = ! this . configurationService . getValue < IDebugConfiguration > ( 'debug' ) . focusEditorOnBreak ;
999
- await this . debugService . focusStackFrame ( undefined , thread , undefined , { preserveFocus } ) ;
1000
- }
1001
-
1002
- if ( thread . stoppedDetails ) {
1003
- if ( thread . stoppedDetails . reason === 'breakpoint' && this . configurationService . getValue < IDebugConfiguration > ( 'debug' ) . openDebug === 'openOnDebugBreak' && ! this . suppressDebugView ) {
1004
- await this . paneCompositeService . openPaneComposite ( VIEWLET_ID , ViewContainerLocation . Sidebar ) ;
980
+ statusQueue . queue ( async ( ) => {
981
+ this . passFocusScheduler . cancel ( ) ;
982
+ this . stoppedDetails . push ( event . body ) ;
983
+ await this . fetchThreads ( event . body ) ;
984
+ // If the focus for the current session is on a non-existent thread, clear the focus.
985
+ const focusedThread = this . debugService . getViewModel ( ) . focusedThread ;
986
+ const focusedThreadDoesNotExist = focusedThread !== undefined && focusedThread . session === this && ! this . threads . has ( focusedThread . threadId ) ;
987
+ if ( focusedThreadDoesNotExist ) {
988
+ this . debugService . focusStackFrame ( undefined , undefined ) ;
989
+ }
990
+ const thread = typeof event . body . threadId === 'number' ? this . getThread ( event . body . threadId ) : undefined ;
991
+ if ( thread ) {
992
+ // Call fetch call stack twice, the first only return the top stack frame.
993
+ // Second retrieves the rest of the call stack. For performance reasons #25605
994
+ const promises = this . model . refreshTopOfCallstack ( < Thread > thread ) ;
995
+ const focus = async ( ) => {
996
+ if ( focusedThreadDoesNotExist || ( ! event . body . preserveFocusHint && thread . getCallStack ( ) . length ) ) {
997
+ const focusedStackFrame = this . debugService . getViewModel ( ) . focusedStackFrame ;
998
+ if ( ! focusedStackFrame || focusedStackFrame . thread . session === this ) {
999
+ // Only take focus if nothing is focused, or if the focus is already on the current session
1000
+ const preserveFocus = ! this . configurationService . getValue < IDebugConfiguration > ( 'debug' ) . focusEditorOnBreak ;
1001
+ await this . debugService . focusStackFrame ( undefined , thread , undefined , { preserveFocus } ) ;
1005
1002
}
1006
1003
1007
- if ( this . configurationService . getValue < IDebugConfiguration > ( 'debug' ) . focusWindowOnBreak && ! this . workbenchEnvironmentService . extensionTestsLocationURI ) {
1008
- await this . hostService . focus ( { force : true /* Application may not be active */ } ) ;
1004
+ if ( thread . stoppedDetails ) {
1005
+ if ( thread . stoppedDetails . reason === 'breakpoint' && this . configurationService . getValue < IDebugConfiguration > ( 'debug' ) . openDebug === 'openOnDebugBreak' && ! this . suppressDebugView ) {
1006
+ await this . paneCompositeService . openPaneComposite ( VIEWLET_ID , ViewContainerLocation . Sidebar ) ;
1007
+ }
1008
+
1009
+ if ( this . configurationService . getValue < IDebugConfiguration > ( 'debug' ) . focusWindowOnBreak && ! this . workbenchEnvironmentService . extensionTestsLocationURI ) {
1010
+ await this . hostService . focus ( { force : true /* Application may not be active */ } ) ;
1011
+ }
1009
1012
}
1010
1013
}
1011
- }
1012
- } ;
1013
-
1014
- await promises . topCallStack ;
1015
- focus ( ) ;
1016
- await promises . wholeCallStack ;
1017
- const focusedStackFrame = this . debugService . getViewModel ( ) . focusedStackFrame ;
1018
- if ( ! focusedStackFrame || ! focusedStackFrame . source || focusedStackFrame . source . presentationHint === 'deemphasize' || focusedStackFrame . presentationHint === 'deemphasize' ) {
1019
- // The top stack frame can be deemphesized so try to focus again #68616
1014
+ } ;
1015
+
1016
+ await promises . topCallStack ;
1020
1017
focus ( ) ;
1018
+ await promises . wholeCallStack ;
1019
+ const focusedStackFrame = this . debugService . getViewModel ( ) . focusedStackFrame ;
1020
+ if ( ! focusedStackFrame || ! focusedStackFrame . source || focusedStackFrame . source . presentationHint === 'deemphasize' || focusedStackFrame . presentationHint === 'deemphasize' ) {
1021
+ // The top stack frame can be deemphesized so try to focus again #68616
1022
+ focus ( ) ;
1023
+ }
1021
1024
}
1022
- }
1023
- this . _onDidChangeState . fire ( ) ;
1025
+ this . _onDidChangeState . fire ( ) ;
1026
+ } ) ;
1024
1027
} ) ) ;
1025
1028
1026
1029
this . rawListeners . push ( this . raw . onDidThread ( event => {
1027
- if ( event . body . reason === 'started' ) {
1028
- // debounce to reduce threadsRequest frequency and improve performance
1029
- if ( ! this . fetchThreadsScheduler ) {
1030
- this . fetchThreadsScheduler = new RunOnceScheduler ( ( ) => {
1031
- this . fetchThreads ( ) ;
1032
- } , 100 ) ;
1033
- this . rawListeners . push ( this . fetchThreadsScheduler ) ;
1034
- }
1035
- if ( ! this . fetchThreadsScheduler . isScheduled ( ) ) {
1036
- this . fetchThreadsScheduler . schedule ( ) ;
1037
- }
1038
- } else if ( event . body . reason === 'exited' ) {
1039
- this . model . clearThreads ( this . getId ( ) , true , event . body . threadId ) ;
1040
- const viewModel = this . debugService . getViewModel ( ) ;
1041
- const focusedThread = viewModel . focusedThread ;
1042
- this . passFocusScheduler . cancel ( ) ;
1043
- if ( focusedThread && event . body . threadId === focusedThread . threadId ) {
1044
- // De-focus the thread in case it was focused
1045
- this . debugService . focusStackFrame ( undefined , undefined , viewModel . focusedSession , { explicit : false } ) ;
1030
+ statusQueue . queue ( async ( ) => {
1031
+ if ( event . body . reason === 'started' ) {
1032
+ // debounce to reduce threadsRequest frequency and improve performance
1033
+ if ( ! this . fetchThreadsScheduler ) {
1034
+ this . fetchThreadsScheduler = new RunOnceScheduler ( ( ) => {
1035
+ this . fetchThreads ( ) ;
1036
+ } , 100 ) ;
1037
+ this . rawListeners . push ( this . fetchThreadsScheduler ) ;
1038
+ }
1039
+ if ( ! this . fetchThreadsScheduler . isScheduled ( ) ) {
1040
+ this . fetchThreadsScheduler . schedule ( ) ;
1041
+ }
1042
+ } else if ( event . body . reason === 'exited' ) {
1043
+ this . model . clearThreads ( this . getId ( ) , true , event . body . threadId ) ;
1044
+ const viewModel = this . debugService . getViewModel ( ) ;
1045
+ const focusedThread = viewModel . focusedThread ;
1046
+ this . passFocusScheduler . cancel ( ) ;
1047
+ if ( focusedThread && event . body . threadId === focusedThread . threadId ) {
1048
+ // De-focus the thread in case it was focused
1049
+ this . debugService . focusStackFrame ( undefined , undefined , viewModel . focusedSession , { explicit : false } ) ;
1050
+ }
1046
1051
}
1047
- }
1052
+ } ) ;
1048
1053
} ) ) ;
1049
1054
1050
1055
this . rawListeners . push ( this . raw . onDidTerminateDebugee ( async event => {
@@ -1057,21 +1062,23 @@ export class DebugSession implements IDebugSession {
1057
1062
} ) ) ;
1058
1063
1059
1064
this . rawListeners . push ( this . raw . onDidContinued ( event => {
1060
- const threadId = event . body . allThreadsContinued !== false ? undefined : event . body . threadId ;
1061
- if ( typeof threadId === 'number' ) {
1062
- this . stoppedDetails = this . stoppedDetails . filter ( sd => sd . threadId !== threadId ) ;
1063
- const tokens = this . cancellationMap . get ( threadId ) ;
1064
- this . cancellationMap . delete ( threadId ) ;
1065
- tokens ?. forEach ( t => t . cancel ( ) ) ;
1066
- } else {
1067
- this . stoppedDetails = [ ] ;
1068
- this . cancelAllRequests ( ) ;
1069
- }
1070
- this . lastContinuedThreadId = threadId ;
1071
- // We need to pass focus to other sessions / threads with a timeout in case a quick stop event occurs #130321
1072
- this . passFocusScheduler . schedule ( ) ;
1073
- this . model . clearThreads ( this . getId ( ) , false , threadId ) ;
1074
- this . _onDidChangeState . fire ( ) ;
1065
+ statusQueue . queue ( async ( ) => {
1066
+ const threadId = event . body . allThreadsContinued !== false ? undefined : event . body . threadId ;
1067
+ if ( typeof threadId === 'number' ) {
1068
+ this . stoppedDetails = this . stoppedDetails . filter ( sd => sd . threadId !== threadId ) ;
1069
+ const tokens = this . cancellationMap . get ( threadId ) ;
1070
+ this . cancellationMap . delete ( threadId ) ;
1071
+ tokens ?. forEach ( t => t . cancel ( ) ) ;
1072
+ } else {
1073
+ this . stoppedDetails = [ ] ;
1074
+ this . cancelAllRequests ( ) ;
1075
+ }
1076
+ this . lastContinuedThreadId = threadId ;
1077
+ // We need to pass focus to other sessions / threads with a timeout in case a quick stop event occurs #130321
1078
+ this . passFocusScheduler . schedule ( ) ;
1079
+ this . model . clearThreads ( this . getId ( ) , false , threadId ) ;
1080
+ this . _onDidChangeState . fire ( ) ;
1081
+ } ) ;
1075
1082
} ) ) ;
1076
1083
1077
1084
const outputQueue = new Queue < void > ( ) ;
0 commit comments