From f4ba87c21e2f207ff1205ede744d6bcf728699b0 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 21 Nov 2019 17:58:24 -0800 Subject: [PATCH 1/2] Fix breakpoint setting deadlock --- .../DebugAdapter/DebugEventHandlerService.cs | 2 +- .../DebugAdapter/DebugStateService.cs | 19 ++++++++++++++++++- .../Handlers/BreakpointHandlers.cs | 8 ++++---- 3 files changed, 23 insertions(+), 6 deletions(-) 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..3bbe97d87 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 SemaphoreSlim _setBreakpointInProgressHandle = AsyncUtils.CreateSimpleLockingSemaphore(); + internal bool NoDebug { get; set; } internal string Arguments { get; set; } @@ -25,8 +31,19 @@ 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(); + } } } 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(); } } From d44fd204d0d133a58e4c955d4584aadd56ecfeb0 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Thu, 21 Nov 2019 18:19:01 -0800 Subject: [PATCH 2/2] codacy issues --- .../Services/DebugAdapter/DebugStateService.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/PowerShellEditorServices/Services/DebugAdapter/DebugStateService.cs b/src/PowerShellEditorServices/Services/DebugAdapter/DebugStateService.cs index 3bbe97d87..0dd5be42e 100644 --- a/src/PowerShellEditorServices/Services/DebugAdapter/DebugStateService.cs +++ b/src/PowerShellEditorServices/Services/DebugAdapter/DebugStateService.cs @@ -11,7 +11,7 @@ namespace Microsoft.PowerShell.EditorServices.Services { internal class DebugStateService { - private SemaphoreSlim _setBreakpointInProgressHandle = AsyncUtils.CreateSimpleLockingSemaphore(); + private readonly SemaphoreSlim _setBreakpointInProgressHandle = AsyncUtils.CreateSimpleLockingSemaphore(); internal bool NoDebug { get; set; } @@ -43,7 +43,8 @@ internal void ReleaseSetBreakpointHandle() internal async Task WaitForSetBreakpointHandleAsync() { - await _setBreakpointInProgressHandle.WaitAsync(); + await _setBreakpointInProgressHandle.WaitAsync() + .ConfigureAwait(continueOnCapturedContext: false); } } }