// Add a work item to the worker queue. private static void AddWorkItem(WorkItem item) { if (!Thread.CanStartThreads()) { // Add the item to the end of the worker queue. if (lastWorkItem != null) { lastWorkItem.next = item; } else { workItems = item; } lastWorkItem = item; // We don't have threads, so execute the items now. WorkItem next = ItemToDispatch(); while (next != null) { next.Execute(); next = ItemToDispatch(); } } else { lock (typeof(ThreadPool)) { if (lastWorkItem != null) { lastWorkItem.next = item; } else { workItems = item; } lastWorkItem = item; // Determine if we need to spawn a new worker thread. if (workItems != null && numWorkerThreads < MaxWorkerThreads) { if (workerThreads == null) { workerThreads = new Thread [MaxWorkerThreads]; } Thread thread = new Thread(new ThreadStart(Work)); #if !ECMA_COMPAT thread.inThreadPool = true; #endif workerThreads[numWorkerThreads++] = thread; thread.IsBackground = true; thread.Start(); } Monitor.Pulse(typeof(ThreadPool)); } } }
private WaitHandle notifyObject; // Who do notify when object disposed // // Private constructor - used to ensure all constructors initialise // the object in the same way. // private Timer(TimerCallback callback, Object state) { // // Validate the parameters. // if (callback == null) { throw new ArgumentNullException("callback"); } // // If this is the first timer constructed allocate resources // for the timer thread and start it. // lock (typeof(Timer)) { if (Timer.alarmClock == null) { if (!Thread.CanStartThreads()) { throw new NotImplementedException(); } Timer.alarmClock = new AlarmClock(); Timer.disposeQueue = new System.Collections.Queue(); Timer.now = Timer.UtcMilliseconds(); Timer.threadWakeup = new AutoResetEvent(false); Timer.timerThread = new Thread(new ThreadStart(Timer.Run)); Timer.timerThread.IsBackground = true; Timer.timerThread.Start(); } } // // Initialize the timer state. // lock (this) { this.disposed = false; this.alarm = Timer.alarmClock.CreateAlarm( new AlarmClock.AlarmExpiredHandler(this.fireTimer)); this.callback = callback; this.state = state; } }
// Add a work item to the completion queue. private static void AddCompletionItem(WorkItem item) { if (!Thread.CanStartThreads()) { // Add the item to the end of the worker queue. if (lastCompletionItem != null) { lastCompletionItem.next = item; } else { completionItems = item; } lastCompletionItem = item; // We don't have threads, so execute the items now. WorkItem next = CompletionItemToDispatch(); while (next != null) { next.Execute(); next = CompletionItemToDispatch(); } } else { lock (completionWait) { if (lastCompletionItem != null) { lastCompletionItem.next = item; } else { 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)); #if !ECMA_COMPAT thread.inThreadPool = true; #endif completionThreads[numCompletionThreads++] = thread; thread.IsBackground = true; thread.Start(); } else { // Signal one of our waiting threads Monitor.Pulse(completionWait); } } } }