Exemplo n.º 1
0
 private void OnThreadPoolThreadExit(ThreadPoolThread exitedThread)
 {
     lock (_sync) {
         if (_idleThreads.Count <= _minThreadCount)
         {
             return;
         }
         Stack <ThreadPoolThread> threads = new Stack <ThreadPoolThread>();
         while (_idleThreads.Count != 0)
         {
             ThreadPoolThread thread = _idleThreads.Pop();
             if (thread == exitedThread)
             {
                 if (!_semaphore.WaitOne(0))
                 {
                     throw new Exception("Semaphore count is invalid.");
                 }
                 break;
             }
             threads.Push(thread);
         }
         while (threads.Count != 0)
         {
             _idleThreads.Push(threads.Pop());
         }
     }
 }
Exemplo n.º 2
0
        /// <summary>
        /// This puts a work request on the queue to be executed.  The logic then immediatly tries to assign a thread the work.
        /// </summary>
        /// <param name="work"></param>
        public void AssignThread(Action work)
        {
            ThreadPoolThread thread      = null;
            Action           currentWork = null;

            lock (_lock)
            {
                if (IsDisposed)
                {
                    return;
                }

                _workQueue.Enqueue(work);
                Interlocked.Increment(ref _workQueueSize);

                if (_availableThreads.Count == 0)
                {
                    return;
                }

                // okay have thread and have work
                thread = _availableThreads.Dequeue();
                Interlocked.Increment(ref _threadsAssigned);

                currentWork = _workQueue.Dequeue(); // this seems strange to deque right after an enqueue but there could be work waiting on the work queue
                Interlocked.Decrement(ref _workQueueSize);
            }

            // we do it here -- the thread and must not be null and should not according to the above logic
            thread.AssignWork(currentWork);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a ThreadPoolThread instance.
        /// </summary>
        /// <param name="id">The id for the thread.</param>
        /// <returns>The created thread</returns>
        private ThreadPoolThread BuildThread(int id)
        {
            ThreadPoolThread thread = new ThreadPoolThread(_poolName, id + 1, ThreadStarting);

            thread.OnFinished += WorkFinished;

            return(thread);
        }
 /// <summary> Puts the thread 't' in the idle list. The thread 't' should be in fact
 /// idle and ready to accept a new target when it joins the idle list.
 ///
 /// <P> An idle thread that is already in the list should never add itself
 /// to the list before it is removed. For efficiency reasons there is no
 /// check to see if the thread is already in the list of idle threads.
 ///
 /// <P> If the idle list was empty 'notify()' will be called on the 'idle'
 /// array, to wake up a thread that might be waiting (within the
 /// 'getIdle()' method) on an idle thread to become available.
 ///
 /// </summary>
 /// <param name="t">The thread to put in the idle list.
 ///
 /// </param>
 private void  putInIdleList(ThreadPoolThread t)
 {
     // NOTE: if already in idle => catastrophe! (should be OK since //
     // this is private method)
     // Lock the idle array to avoid races with 'getIdle()'
     lock (idle)
     {
         idle[nidle] = t;
         nidle++;
         // If idle array was empty wakeup any waiting threads.
         if (nidle == 1)
         {
             System.Threading.Monitor.Pulse(idle);
         }
     }
 }
Exemplo n.º 5
0
 /// <summary>
 /// Fires the OnNewThreadPoolThread event.
 /// </summary>
 /// <param name="thread"></param>
 private void ThreadStarting(ThreadPoolThread thread)
 {
     if (null != OnNewThreadPoolThread)
     {
         try
         {
             OnNewThreadPoolThread(this, new NewThreadPoolThreadArgs()
             {
                 name   = thread.Name,
                 thread = thread.Thread
             });
         }
         catch (Exception)
         {
             throw;
         }
     }
 }
        /// <summary> Creates a new thread pool of the given size, thread priority and pool
        /// name.
        ///
        /// <P>If the Java system property of the name defined by
        /// 'CONCURRENCY_PROP_NAME' is set, then an attempt will be made to load
        /// the library that supports concurrency setting (see
        /// 'NativeServices'). If that succeds the concurrency level will be set to
        /// the specified value. Otherwise a warning is printed.
        ///
        /// </summary>
        /// <param name="size">The size of the pool (number of threads to create in the
        /// pool).
        ///
        /// </param>
        /// <param name="priority">The priority to give to the threads in the pool. If
        /// less than 'Thread.MIN_PRIORITY' it will be the same as the priority of
        /// the calling thread.
        ///
        /// </param>
        /// <param name="name">The name of the pool. If null a default generic name is
        /// chosen.
        ///
        /// </param>
        /// <seealso cref="NativeServices">
        ///
        /// </seealso>
        /// <seealso cref="CONCURRENCY_PROP_NAME">
        ///
        /// </seealso>
        public ThreadPool(int size, int priority, System.String name)
        {
            int i;
            ThreadPoolThread t;

            //System.String prop;
            //int clevel;

            // Initialize variables checking for special cases
            if (size <= 0)
            {
                throw new System.ArgumentException("Pool must be of positive size");
            }
            if (priority < (int)System.Threading.ThreadPriority.Lowest)
            {
                poolPriority = (System.Int32)SupportClass.ThreadClass.Current().Priority;
            }
            else
            {
                poolPriority = (priority < (int)System.Threading.ThreadPriority.Highest)?priority:(int)System.Threading.ThreadPriority.Highest;
            }
            if (name == null)
            {
                poolName = "Anonymous ThreadPool";
            }
            else
            {
                poolName = name;
            }

            // Allocate internal variables
            idle  = new ThreadPoolThread[size];
            nidle = 0;

            // Create and start the threads
            for (i = 0; i < size; i++)
            {
                t = new ThreadPoolThread(this, i, poolName + "-" + i);
                t.Start();
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Kills the assigned work off that is in a thread.
        /// </summary>
        /// <param name="work"></param>
        public void KillThread(Action work)
        {
            ThreadPoolThread t = null;

            lock (_lock)
            {
                int cnt = _allThreads.Length;
                for (int i = 0; i < cnt; i++)
                {
                    t = _allThreads[i];
                    if (t.Work == work)
                    {
                        goto kill_it;
                    }
                }
                return;
            }

kill_it:
            t.KillWork();
        }
Exemplo n.º 8
0
        /// <summary>
        /// This is called by the ThreadPoolThread when it's finished processing the unit of work it was given.
        /// </summary>
        /// <param name="thread">The thread that finished</param>
        private void WorkFinished(ThreadPoolThread thread)
        {
            if (IsDisposed)
            {
                return;
            }

            Action currentWork = null;

            lock (_lock)
            {
                if (_workQueue.Count > 0)
                {
                    currentWork = _workQueue.Dequeue();
                    Interlocked.Decrement(ref _workQueueSize);
                }
                else
                {
                    _availableThreads.Enqueue(thread);
                    Interlocked.Decrement(ref _threadsAssigned);
                }
            }

            if (null != currentWork)
            {
                thread.AssignWork(currentWork);
            }

            if (null != OnThreadFinished)
            {
                try
                {
                    OnThreadFinished(this, new EventArgs());
                }
                catch (Exception)
                { }
            }
        }
Exemplo n.º 9
0
 public void QueueWorkItem(Action action)
 {
     _schedulerThread.QueueWorkItem(() => {
         ThreadPoolThread thread;
         if (_semaphore.WaitOne(_threadCreationDelay))
         {
             lock (_sync) {
                 thread = _idleThreads.Pop();
             }
         }
         else
         {
             thread = new ThreadPoolThread(this);
         }
         thread.QueueWorkItem(action);
         thread.QueueWorkItem(() => {
             lock (_sync) {
                 _idleThreads.Push(thread);
                 _semaphore.Release();
             }
         });
     });
 }
Exemplo n.º 10
0
		/// <summary> Puts the thread 't' in the idle list. The thread 't' should be in fact
		/// idle and ready to accept a new target when it joins the idle list.
		/// 
		/// <P> An idle thread that is already in the list should never add itself
		/// to the list before it is removed. For efficiency reasons there is no
		/// check to see if the thread is already in the list of idle threads.
		/// 
		/// <P> If the idle list was empty 'notify()' will be called on the 'idle'
		/// array, to wake up a thread that might be waiting (within the
		/// 'getIdle()' method) on an idle thread to become available.
		/// 
		/// </summary>
		/// <param name="t">The thread to put in the idle list.
		/// 
		/// </param>
		private void  putInIdleList(ThreadPoolThread t)
		{
			// NOTE: if already in idle => catastrophe! (should be OK since //
			// this is private method)
			// Lock the idle array to avoid races with 'getIdle()'
			lock (idle)
			{
				idle[nidle] = t;
				nidle++;
				// If idle array was empty wakeup any waiting threads.
				if (nidle == 1)
					System.Threading.Monitor.Pulse(idle);
			}
		}
Exemplo n.º 11
0
		/// <summary> Creates a new thread pool of the given size, thread priority and pool
		/// name.
		/// 
		/// <P>If the Java system property of the name defined by
		/// 'CONCURRENCY_PROP_NAME' is set, then an attempt will be made to load
		/// the library that supports concurrency setting (see
		/// 'NativeServices'). If that succeds the concurrency level will be set to 
		/// the specified value. Otherwise a warning is printed.
		/// 
		/// </summary>
		/// <param name="size">The size of the pool (number of threads to create in the
		/// pool).
		/// 
		/// </param>
		/// <param name="priority">The priority to give to the threads in the pool. If
		/// less than 'Thread.MIN_PRIORITY' it will be the same as the priority of
		/// the calling thread.
		/// 
		/// </param>
		/// <param name="name">The name of the pool. If null a default generic name is
		/// chosen.
		/// 
		/// </param>
		/// <seealso cref="NativeServices">
		/// 
		/// </seealso>
		/// <seealso cref="CONCURRENCY_PROP_NAME">
		/// 
		/// </seealso>
		public ThreadPool(int size, int priority, System.String name)
		{
			int i;
			ThreadPoolThread t;
			//System.String prop;
			//int clevel;
			
			// Initialize variables checking for special cases
			if (size <= 0)
			{
				throw new System.ArgumentException("Pool must be of positive size");
			}
			if (priority < (int) System.Threading.ThreadPriority.Lowest)
			{
				poolPriority = (System.Int32) SupportClass.ThreadClass.Current().Priority;
			}
			else
			{
				poolPriority = (priority < (int) System.Threading.ThreadPriority.Highest)?priority:(int) System.Threading.ThreadPriority.Highest;
			}
			if (name == null)
			{
				poolName = "Anonymous ThreadPool";
			}
			else
			{
				poolName = name;
			}
					
			// Allocate internal variables
			idle = new ThreadPoolThread[size];
			nidle = 0;
			
			// Create and start the threads
			for (i = 0; i < size; i++)
			{
				t = new ThreadPoolThread(this, i, poolName + "-" + i);
				t.Start();
			}
		}