123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- using System;
- using System.Collections.Generic;
- using ST = System.Threading;
- namespace SharpCifs.Util.Sharpen
- {
- class ThreadPoolExecutor
- {
- ThreadFactory _tf;
- int _corePoolSize;
- int _maxPoolSize;
- List<Thread> _pool = new List<Thread> ();
- int _runningThreads;
- int _freeThreads;
- bool _shutdown;
- Queue<IRunnable> _pendingTasks = new Queue<IRunnable> ();
-
- public ThreadPoolExecutor (int corePoolSize, ThreadFactory factory)
- {
- this._corePoolSize = corePoolSize;
- _maxPoolSize = corePoolSize;
- _tf = factory;
- }
-
- public void SetMaximumPoolSize (int size)
- {
- _maxPoolSize = size;
- }
-
- public bool IsShutdown ()
- {
- return _shutdown;
- }
-
- public virtual bool IsTerminated ()
- {
- lock (_pendingTasks) {
- return _shutdown && _pendingTasks.Count == 0;
- }
- }
-
- public virtual bool IsTerminating ()
- {
- lock (_pendingTasks) {
- return _shutdown && !IsTerminated ();
- }
- }
-
- public int GetCorePoolSize ()
- {
- return _corePoolSize;
- }
-
- public void PrestartAllCoreThreads ()
- {
- lock (_pendingTasks) {
- while (_runningThreads < _corePoolSize)
- StartPoolThread ();
- }
- }
-
- public void SetThreadFactory (ThreadFactory f)
- {
- _tf = f;
- }
-
- public void Execute (IRunnable r)
- {
- InternalExecute (r, true);
- }
-
- internal void InternalExecute (IRunnable r, bool checkShutdown)
- {
- lock (_pendingTasks) {
- if (_shutdown && checkShutdown)
- throw new InvalidOperationException ();
- if (_runningThreads < _corePoolSize) {
- StartPoolThread ();
- }
- else if (_freeThreads > 0) {
- _freeThreads--;
- }
- else if (_runningThreads < _maxPoolSize) {
- StartPoolThread ();
- }
- _pendingTasks.Enqueue (r);
- ST.Monitor.PulseAll (_pendingTasks);
- }
- }
-
- void StartPoolThread ()
- {
- _runningThreads++;
- _pool.Add (_tf.NewThread (new RunnableAction (RunPoolThread)));
- }
-
- public void RunPoolThread ()
- {
- while (!IsTerminated ()) {
- try {
- IRunnable r = null;
- lock (_pendingTasks) {
- _freeThreads++;
- while (!IsTerminated () && _pendingTasks.Count == 0)
- ST.Monitor.Wait (_pendingTasks);
- if (IsTerminated ())
- break;
- r = _pendingTasks.Dequeue ();
- }
- if (r != null)
- r.Run ();
- }
- //supress all errors, anyway
- //catch (ST.ThreadAbortException) {
- // // Do not catch a thread abort. If we've been aborted just let the thread die.
- // // Currently reseting an abort which was issued because the appdomain is being
- // // torn down results in the process living forever and consuming 100% cpu time.
- // return;
- //}
- catch {
- }
- }
- }
-
- public virtual void Shutdown ()
- {
- lock (_pendingTasks) {
- _shutdown = true;
- ST.Monitor.PulseAll (_pendingTasks);
- }
- }
-
- public virtual List<IRunnable> ShutdownNow ()
- {
- lock (_pendingTasks) {
- _shutdown = true;
- foreach (var t in _pool) {
- try {
- t.Abort ();
- } catch {}
- }
- _pool.Clear ();
- _freeThreads = 0;
- _runningThreads = 0;
- var res = new List<IRunnable> (_pendingTasks);
- _pendingTasks.Clear ();
- return res;
- }
- }
- }
-
- class RunnableAction: IRunnable
- {
- Action _action;
-
- public RunnableAction (Action a)
- {
- _action = a;
- }
-
- public void Run ()
- {
- _action ();
- }
- }
- }
|