Пример #1
0
        // 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));
                }
            }
        }
Пример #2
0
        // Run a worker thread.
        private static void Work()
        {
            // Assert unrestricted permissions for this thread.
            // The permissions will be modified for each work item
            // to reflect the context that created the work item.
            ClrSecurity.SetPermissions(null, 0);

            // Wait for and dispatch work items.
            WorkItem item = null;

            for (;;)
            {
                lock (typeof(ThreadPool))
                {
                    do
                    {
                        item = ItemToDispatch();
                        if (item == null)
                        {
                            Monitor.Wait(typeof(ThreadPool));
                        }
                    }while(item == null);
                }

                try
                {
                    Interlocked.Increment(ref usedWorkerThreads);
                    item.Execute();
                }
                finally
                {
                    item = null;
                    Interlocked.Decrement(ref usedWorkerThreads);
                }
            }
        }
Пример #3
0
        // 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);
                    }
                }
            }
        }