# Patch created by root # Date: Wed Jun 2 04:43:03 MDT 2004 # Repository: pnetlib # Comments: # Removed the exception, and instead left completion units in the queue and pulsed the lock object if there were any waiting completion threads. #### 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 2 Jun 2004 10:43:05 -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,476 **** 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)); --- 465,496 ---- 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"); { ! // Don't throw. Leave on the queue and pulse the lock if there are any waiting threads ! if( usedCompletionThreads < numCompletionThreads ) ! Monitor.Pulse(completionWait); ! return; } Thread thread = new Thread(new ThreadStart(Complete)); *************** *** 481,487 **** thread.IsBackground = true; thread.Start(); } ! Monitor.Pulse(completionWait); } } } --- 501,511 ---- thread.IsBackground = true; thread.Start(); } ! else ! { ! // Signal one of our waiting threads ! Monitor.Pulse(completionWait); ! } } } } #### End of Patch data ####