From 090854708334f6b4dc69a0fbdd1da034b6b18ca2 Mon Sep 17 00:00:00 2001 From: Chunqing Chen Date: Tue, 18 Oct 2016 17:32:56 -0700 Subject: [PATCH] Remove the unnecessary use of lock in PseudoParameterBinder to avoid deadlock (#2501) This is the fix to MSFT:9039127 [RFC] : SMA Jobs stop processing, show various status but never change or progress; due to deadlock in sandbox process. The fix is brought to GitHub to make sure GitHub powershell always has the latest changes. --- .../PseudoParameterBinder.cs | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs index d1ea4af2e0..957d2335ed 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/PseudoParameterBinder.cs @@ -333,24 +333,21 @@ namespace System.Management.Automation.Language PseudoBindingInfo pseudoBinding = null; if (Runspace.DefaultRunspace == null) { - lock (s_bindCommandLock) + // Handle static binding from a non-PowerShell / C# application + // DefaultRunspace is a thread static field, so race condition will not happen because different threads will access different instances of "DefaultRunspace" + if (s_bindCommandRunspace == null) { - if (s_bindCommandPowerShell == null) - { - // Create a mini runspace by remove the types and formats - InitialSessionState minimalState = InitialSessionState.CreateDefault2(); - minimalState.Types.Clear(); - minimalState.Formats.Clear(); - - s_bindCommandPowerShell = PowerShell.Create(minimalState); - } - - // Handle static binding from a non-PowerShell / C# application - Runspace.DefaultRunspace = s_bindCommandPowerShell.Runspace; - // Static binding always does argument binding (not argument or parameter completion). - pseudoBinding = new PseudoParameterBinder().DoPseudoParameterBinding(commandAst, null, null, PseudoParameterBinder.BindingType.ArgumentBinding); - Runspace.DefaultRunspace = null; + // Create a mini runspace by remove the types and formats + InitialSessionState minimalState = InitialSessionState.CreateDefault2(); + minimalState.Types.Clear(); + minimalState.Formats.Clear(); + s_bindCommandRunspace = RunspaceFactory.CreateRunspace(minimalState); + s_bindCommandRunspace.Open(); } + Runspace.DefaultRunspace = s_bindCommandRunspace; + // Static binding always does argument binding (not argument or parameter completion). + pseudoBinding = new PseudoParameterBinder().DoPseudoParameterBinding(commandAst, null, null, PseudoParameterBinder.BindingType.ArgumentBinding); + Runspace.DefaultRunspace = null; } else { @@ -360,8 +357,8 @@ namespace System.Management.Automation.Language return new StaticBindingResult(commandAst, pseudoBinding); } - private static Object s_bindCommandLock = new Object(); - private static PowerShell s_bindCommandPowerShell = null; + [ThreadStatic] + static Runspace s_bindCommandRunspace = null; } ///