@@ -20,6 +20,15 @@ namespace System.Management.Automation.Runspaces |
20 | 20 | /// </summary> |
21 | 21 | internal sealed class LocalPipeline : PipelineBase |
22 | 22 | { |
| 23 | + // Default stack size in bytes for local pipeline threads. |
| 24 | + // |
| 25 | + // Each platform uses different default for the thread stack size: |
| 26 | + // - Windows 2 MB |
| 27 | + // - Linux 8 Mb |
| 28 | + // - MacOs 512 KB |
| 29 | + // We should use the same default for all platforms to get predictable behavior. |
| 30 | + internal const int DefaultPipelineStackSize = 10_000_000; |
| 31 | + |
23 | 32 | #region constructors |
24 | 33 |
|
25 | 34 | /// <summary> |
@@ -152,12 +161,12 @@ protected override void StartPipelineExecution() |
152 | 161 | #if CORECLR |
153 | 162 | //Start execution of pipeline in another thread |
154 | 163 | // No ApartmentState/ThreadStackSize In CoreCLR |
155 | | - Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc)); |
| 164 | + Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc), DefaultPipelineStackSize); |
156 | 165 | SetupInvokeThread(invokeThread, true); |
157 | 166 | #else |
158 | 167 | //Start execution of pipeline in another thread |
159 | 168 | // 2004/05/02-JonN Specify maxStack parameter |
160 | | - Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc), MaxStack); |
| 169 | + Thread invokeThread = new Thread(new ThreadStart(this.InvokeThreadProc), DefaultPipelineStackSize); |
161 | 170 | SetupInvokeThread(invokeThread, true); |
162 | 171 |
|
163 | 172 | ApartmentState apartmentState; |
@@ -245,55 +254,6 @@ private void SetupInvokeThread(Thread invokeThread, bool changeName) |
245 | 254 | } |
246 | 255 | } |
247 | 256 |
|
248 | | -#if !CORECLR |
249 | | - /// <summary> |
250 | | - /// Stack Reserve setting for pipeline threads |
251 | | - /// </summary> |
252 | | - internal static int MaxStack |
253 | | - { |
254 | | - get |
255 | | - { |
256 | | - int i = ReadRegistryInt("PipelineMaxStackSizeMB", 10); |
257 | | - if (i < 10) |
258 | | - i = 10; // minimum 10MB |
259 | | - else if (i > 100) |
260 | | - i = 100; // maximum 100MB |
261 | | - return i * 1000000; |
262 | | - } |
263 | | - } |
264 | | - |
265 | | - internal static int ReadRegistryInt(string policyValueName, int defaultValue) |
266 | | - { |
267 | | - RegistryKey key; |
268 | | - try |
269 | | - { |
270 | | - key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds"); |
271 | | - } |
272 | | - catch (System.Security.SecurityException) |
273 | | - { |
274 | | - return defaultValue; |
275 | | - } |
276 | | - if (null == key) |
277 | | - return defaultValue; |
278 | | - |
279 | | - object temp; |
280 | | - try |
281 | | - { |
282 | | - temp = key.GetValue(policyValueName); |
283 | | - } |
284 | | - catch (System.Security.SecurityException) |
285 | | - { |
286 | | - return defaultValue; |
287 | | - } |
288 | | - if (!(temp is int)) |
289 | | - { |
290 | | - return defaultValue; |
291 | | - } |
292 | | - int i = (int)temp; |
293 | | - return i; |
294 | | - } |
295 | | -#endif |
296 | | - |
297 | 257 | ///<summary> |
298 | 258 | /// Helper method for asynchronous invoke |
299 | 259 | ///<returns>Unhandled FlowControl exception if InvocationSettings.ExposeFlowControlExceptions is true.</returns> |
@@ -1219,25 +1179,25 @@ protected override |
1219 | 1179 | } |
1220 | 1180 |
|
1221 | 1181 | /// <summary> |
1222 | | - /// Helper class that holds the thread used to execute pipelines when CreateThreadOptions.ReuseThread is used |
| 1182 | + /// Helper class that holds the thread used to execute pipelines when CreateThreadOptions.ReuseThread is used. |
1223 | 1183 | /// </summary> |
1224 | 1184 | internal class PipelineThread : IDisposable |
1225 | 1185 | { |
1226 | 1186 | /// <summary> |
1227 | | - /// Creates the worker thread and waits for it to be ready |
| 1187 | + /// Creates the worker thread and waits for it to be ready. |
1228 | 1188 | /// </summary> |
1229 | 1189 | #if CORECLR |
1230 | 1190 | internal PipelineThread() |
1231 | 1191 | { |
1232 | | - _worker = new Thread(WorkerProc); |
| 1192 | + _worker = new Thread(WorkerProc, LocalPipeline.DefaultPipelineStackSize); |
1233 | 1193 | _workItem = null; |
1234 | 1194 | _workItemReady = new AutoResetEvent(false); |
1235 | 1195 | _closed = false; |
1236 | 1196 | } |
1237 | 1197 | #else |
1238 | 1198 | internal PipelineThread(ApartmentState apartmentState) |
1239 | 1199 | { |
1240 | | - _worker = new Thread(WorkerProc, LocalPipeline.MaxStack); |
| 1200 | + _worker = new Thread(WorkerProc, DefaultPipelineStackSize); |
1241 | 1201 | _workItem = null; |
1242 | 1202 | _workItemReady = new AutoResetEvent(false); |
1243 | 1203 | _closed = false; |
|