diff --git a/STPTests/TestThreadsCreate.cs b/STPTests/TestThreadsCreate.cs index 6cf5455..d5488d9 100644 --- a/STPTests/TestThreadsCreate.cs +++ b/STPTests/TestThreadsCreate.cs @@ -63,6 +63,48 @@ namespace SmartThreadPoolTests int counter = ThreadContextState.Current.Counter; _termSuccess = (1111 == counter); } + + + // Can't run this test, StackOverflowException crashes the application and can't be catched and ignored + //[Test] + public void NotTestThreadsMaxStackSize() + { + STPStartInfo stpStartInfo = new STPStartInfo() + { + MaxStackSize = 64 * 1024, + }; + + SmartThreadPool stp = new SmartThreadPool(stpStartInfo); + stp.Start(); + + IWorkItemResult wir = stp.QueueWorkItem(() => AllocateBufferOnStack(10 * 1024)); + + bool result = wir.GetResult(); + Assert.IsTrue(result); + + wir = stp.QueueWorkItem(() => AllocateBufferOnStack(1000 * 1024)); + + result = wir.GetResult(); + Assert.IsFalse(result); + } + + private static unsafe bool AllocateBufferOnStack(int size) + { + try + { + byte* p = stackalloc byte[size]; + } + catch (StackOverflowException ex) + { + return false; + } + catch (Exception ex) + { + return false; + } + + return true; + } } internal class ThreadContextState diff --git a/SmartThreadPool/STPStartInfo.cs b/SmartThreadPool/STPStartInfo.cs index 440a28d..96fa094 100644 --- a/SmartThreadPool/STPStartInfo.cs +++ b/SmartThreadPool/STPStartInfo.cs @@ -18,6 +18,7 @@ namespace Amib.Threading private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground; private bool _enableLocalPerformanceCounters; private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName; + private int? _maxStackSize = SmartThreadPool.DefaultMaxStackSize; public STPStartInfo() { @@ -184,7 +185,28 @@ namespace Amib.Threading ThrowIfReadOnly(); _apartmentState = value; } + } + +#if !(_SILVERLIGHT) && !(WINDOWS_PHONE) + + /// + /// Get/Set the max stack size of threads in the thread pool + /// + public int? MaxStackSize + { + get { return _maxStackSize; } + set + { + ThrowIfReadOnly(); + if (value.HasValue && value.Value < 0) + { + throw new ArgumentOutOfRangeException("value", "Value must be greater than 0."); + } + _maxStackSize = value; + } } +#endif + #endif } } diff --git a/SmartThreadPool/SmartThreadPool.cs b/SmartThreadPool/SmartThreadPool.cs index b30f877..a4f4ce5 100644 --- a/SmartThreadPool/SmartThreadPool.cs +++ b/SmartThreadPool/SmartThreadPool.cs @@ -89,6 +89,11 @@ // - Added IsBackground option to threads // - Added ApartmentState to threads // - Fixed thread creation when queuing many work items at the same time. +// +// 24 August 2012 - Changes: +// - Enabled cancel abort after cancel. See: http://smartthreadpool.codeplex.com/discussions/345937 by alecswan +// - Added option to set MaxStackSize of threads + #endregion using System; @@ -180,6 +185,11 @@ namespace Amib.Threading /// public const string DefaultThreadPoolName = "SmartThreadPool"; + /// + /// The default Max Stack Size. (SmartThreadPool) + /// + public static readonly int? DefaultMaxStackSize = null; + /// /// The default fill state with params. (false) /// It is relevant only to QueueWorkItem of Action<...>/Func<...> @@ -656,9 +666,16 @@ namespace Amib.Threading return; } - // Create a new thread - Thread workerThread = new Thread(ProcessQueuedItems); + // Create a new thread +#if (_SILVERLIGHT) || (WINDOWS_PHONE) + Thread workerThread = new Thread(ProcessQueuedItems); +#else + Thread workerThread = + _stpStartInfo.MaxStackSize.HasValue + ? new Thread(ProcessQueuedItems, _stpStartInfo.MaxStackSize.Value) + : new Thread(ProcessQueuedItems); +#endif // Configure the new thread and start it workerThread.Name = "STP " + Name + " Thread #" + _threadCounter; workerThread.IsBackground = _stpStartInfo.AreThreadsBackground;