diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/DebugEventHandlerService.cs b/src/PowerShellEditorServices/Services/DebugAdapter/DebugEventHandlerService.cs index da867637e..9e48625b5 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/DebugEventHandlerService.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/DebugEventHandlerService.cs @@ -128,7 +128,7 @@ private void DebugService_BreakpointUpdated(object sender, BreakpointUpdatedEven { string reason = "changed"; - if (_debugStateService.SetBreakpointInProgress) + if (_debugStateService.IsSetBreakpointInProgress) { // Don't send breakpoint update notifications when setting // breakpoints on behalf of the client. diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/DebugStateService.cs b/src/PowerShellEditorServices/Services/DebugAdapter/DebugStateService.cs index c5b755358..0dd5be42e 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/DebugStateService.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/DebugStateService.cs @@ -3,10 +3,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +using System.Threading; +using System.Threading.Tasks; +using Microsoft.PowerShell.EditorServices.Utility; + namespace Microsoft.PowerShell.EditorServices.Services { internal class DebugStateService { + private readonly SemaphoreSlim _setBreakpointInProgressHandle = AsyncUtils.CreateSimpleLockingSemaphore(); + internal bool NoDebug { get; set; } internal string Arguments { get; set; } @@ -25,8 +31,20 @@ internal class DebugStateService internal bool IsInteractiveDebugSession { get; set; } - internal bool SetBreakpointInProgress { get; set; } + // If the CurrentCount is equal to zero, then we have some thread using the handle. + internal bool IsSetBreakpointInProgress => _setBreakpointInProgressHandle.CurrentCount == 0; internal bool IsUsingTempIntegratedConsole { get; set; } + + internal void ReleaseSetBreakpointHandle() + { + _setBreakpointInProgressHandle.Release(); + } + + internal async Task WaitForSetBreakpointHandleAsync() + { + await _setBreakpointInProgressHandle.WaitAsync() + .ConfigureAwait(continueOnCapturedContext: false); + } } } diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/BreakpointHandlers.cs b/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/BreakpointHandlers.cs index 8b65c4eea..637976fbc 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/BreakpointHandlers.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/Handlers/BreakpointHandlers.cs @@ -48,7 +48,7 @@ public async Task Handle(SetFunctionBreakpointsA CommandBreakpointDetails[] updatedBreakpointDetails = breakpointDetails; if (!_debugStateService.NoDebug) { - _debugStateService.SetBreakpointInProgress = true; + await _debugStateService.WaitForSetBreakpointHandleAsync(); try { @@ -63,7 +63,7 @@ await _debugService.SetCommandBreakpointsAsync( } finally { - _debugStateService.SetBreakpointInProgress = false; + _debugStateService.ReleaseSetBreakpointHandle(); } } @@ -196,7 +196,7 @@ public async Task Handle(SetBreakpointsArguments request BreakpointDetails[] updatedBreakpointDetails = breakpointDetails; if (!_debugStateService.NoDebug) { - _debugStateService.SetBreakpointInProgress = true; + await _debugStateService.WaitForSetBreakpointHandleAsync(); try { @@ -212,7 +212,7 @@ await _debugService.SetLineBreakpointsAsync( } finally { - _debugStateService.SetBreakpointInProgress = false; + _debugStateService.ReleaseSetBreakpointHandle(); } }