# Patch created by root # Date: Tue Jun 1 11:50:27 MDT 2004 # Repository: pnetlib # Comments: # Preventing ThreadPool from creating 16 completion threads just because it can. Added code to check for the number of threads needed, and just making sure that a minimum number of threads are started to support the completion thread queue. #### End of Preamble #### #### Patch data follows #### Index: runtime/System/Threading/ThreadPool.cs =================================================================== RCS file: /cvsroot/dotgnu-pnet/pnetlib/runtime/System/Threading/ThreadPool.cs,v retrieving revision 1.7 diff -c -r1.7 ThreadPool.cs *** runtime/System/Threading/ThreadPool.cs 28 May 2004 22:17:41 -0000 1.7 --- runtime/System/Threading/ThreadPool.cs 1 Jun 2004 17:51:34 -0000 *************** *** 42,47 **** --- 42,48 ---- // Internal state. private static int usedWorkerThreads; private static int usedCompletionThreads; + private static int queuedCompletionItems; private static WorkItem workItems, lastWorkItem; private static WorkItem completionItems, lastCompletionItem; private static Thread[] workerThreads; *************** *** 350,366 **** } } while (item == null); } try { - Interlocked.Increment(ref usedCompletionThreads); item.Execute(); } finally { item = null; ! Interlocked.Decrement(ref usedCompletionThreads); } } } --- 351,369 ---- } } while (item == null); + usedCompletionThreads++; + queuedCompletionItems--; } try { item.Execute(); } finally { item = null; ! lock(completionWait) ! usedCompletionThreads--; } } } *************** *** 440,446 **** completionItems = item; } lastCompletionItem = item; ! // We don't have threads, so execute the items now. WorkItem next = CompletionItemToDispatch(); while(next != null) --- 443,449 ---- completionItems = item; } lastCompletionItem = item; ! // We don't have threads, so execute the items now. WorkItem next = CompletionItemToDispatch(); while(next != null) *************** *** 462,477 **** completionItems = item; } lastCompletionItem = item; ! // Determine if we need to spawn a new completion thread. ! if(completionItems != null && ! numCompletionThreads < MaxCompletionThreads) ! { ! if(completionThreads == null) ! { completionThreads = new Thread [MaxCompletionThreads]; ! } Thread thread = new Thread(new ThreadStart(Complete)); #if !ECMA_COMPAT --- 465,491 ---- completionItems = item; } lastCompletionItem = item; + queuedCompletionItems++; ! if( completionThreads == null ) completionThreads = new Thread [MaxCompletionThreads]; ! ! // ! // We need to make sure that there are enough threads to ! // handle the entire queue. ! // ! // There is a small possibility here that there is a thread ! // about to end that could take this work unit, but we have no ! // way of knowing that. ! // ! int needThreads = usedCompletionThreads + queuedCompletionItems; ! ! // Determine if we need to spawn a new completion thread. ! if( needThreads > numCompletionThreads ) ! { ! if( needThreads > MaxCompletionThreads ) ! throw new SystemException("Number of completion threads required exceeds maximum"); Thread thread = new Thread(new ThreadStart(Complete)); #if !ECMA_COMPAT *************** *** 481,487 **** thread.IsBackground = true; thread.Start(); } ! Monitor.Pulse(completionWait); } } } --- 495,505 ---- thread.IsBackground = true; thread.Start(); } ! else ! { ! // Signal one of our waiting threads ! Monitor.Pulse(completionWait); ! } } } } #### End of Patch data ####