123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- 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.Cancel(true);
- t.Dispose();
- }
- 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();
- }
- }
- }
|