diff --git a/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs b/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs index 5ed6faaff38..472b38a9334 100644 --- a/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs +++ b/src/System.Management.Automation/engine/hostifaces/LocalPipeline.cs @@ -20,6 +20,14 @@ namespace System.Management.Automation.Runspaces /// internal sealed class LocalPipeline : PipelineBase { + // Each OS platform uses different default stack size for threads: + // - Windows 2 MB + // - Linux 8 Mb + // - MacOs 512 KB + // We should use the same stack size for pipeline threads on all platforms to get predictable behavior. + // The stack size we use for pipeline threads is 10MB, which is inherited from Windows PowerShell. + internal const int DefaultPipelineStackSize = 10_000_000; + #region constructors /// @@ -149,17 +157,11 @@ protected override void StartPipelineExecution() case PSThreadOptions.Default: case PSThreadOptions.UseNewThread: { -#if CORECLR - //Start execution of pipeline in another thread - // No ApartmentState/ThreadStackSize In CoreCLR - Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc)); - SetupInvokeThread(invokeThread, true); -#else - //Start execution of pipeline in another thread - // 2004/05/02-JonN Specify maxStack parameter - Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc), MaxStack); + // Start execution of pipeline in another thread + Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc), DefaultPipelineStackSize); SetupInvokeThread(invokeThread, true); - +#if !CORECLR + // No ApartmentState in CoreCLR ApartmentState apartmentState; if (InvocationSettings != null && InvocationSettings.ApartmentState != ApartmentState.Unknown) @@ -245,55 +247,6 @@ private void SetupInvokeThread(Thread invokeThread, bool changeName) } } -#if !CORECLR - /// - /// Stack Reserve setting for pipeline threads - /// - internal static int MaxStack - { - get - { - int i = ReadRegistryInt("PipelineMaxStackSizeMB", 10); - if (i < 10) - i = 10; // minimum 10MB - else if (i > 100) - i = 100; // maximum 100MB - return i * 1000000; - } - } - - internal static int ReadRegistryInt(string policyValueName, int defaultValue) - { - RegistryKey key; - try - { - key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds"); - } - catch (System.Security.SecurityException) - { - return defaultValue; - } - if (null == key) - return defaultValue; - - object temp; - try - { - temp = key.GetValue(policyValueName); - } - catch (System.Security.SecurityException) - { - return defaultValue; - } - if (!(temp is int)) - { - return defaultValue; - } - int i = (int)temp; - return i; - } -#endif - /// /// Helper method for asynchronous invoke ///Unhandled FlowControl exception if InvocationSettings.ExposeFlowControlExceptions is true. @@ -1219,17 +1172,17 @@ protected override } /// - /// Helper class that holds the thread used to execute pipelines when CreateThreadOptions.ReuseThread is used + /// Helper class that holds the thread used to execute pipelines when CreateThreadOptions.ReuseThread is used. /// internal class PipelineThread : IDisposable { /// - /// Creates the worker thread and waits for it to be ready + /// Creates the worker thread and waits for it to be ready. /// #if CORECLR internal PipelineThread() { - _worker = new Thread(WorkerProc); + _worker = new Thread(WorkerProc, LocalPipeline.DefaultPipelineStackSize); _workItem = null; _workItemReady = new AutoResetEvent(false); _closed = false; @@ -1237,7 +1190,7 @@ internal PipelineThread() #else internal PipelineThread(ApartmentState apartmentState) { - _worker = new Thread(WorkerProc, LocalPipeline.MaxStack); + _worker = new Thread(WorkerProc, LocalPipeline.DefaultPipelineStackSize); _workItem = null; _workItemReady = new AutoResetEvent(false); _closed = false;