// // System.Threading.ThreadPool // // Author: // Patrik Torstensson (patrik.torstensson@labs2.com) // Dick Porter (dick@ximian.com) // // (C) Ximian, Inc. http://www.ximian.com // (C) Patrik Torstensson // using System; using System.Collections; namespace System.Threading { /// (Patrik T notes) /// This threadpool is focused on saving resources not giving max performance. /// /// Note, this class is not perfect but it works. ;-) Should also replace /// the queue with an internal one (performance) /// /// This class should also use a specialized queue to increase performance.. /// 0 && _RequestInQueue > _ThreadCreateTriggerRequests) { bCreateThread = true; } if (bCreateThread) { Interlocked.Increment(ref _CurrentThreads); Thread Start = new Thread(new ThreadStart(WorkerThread)); Start.Start(); Start.IsThreadPoolThreadInternal = true; _Threads.Add(Start); } } internal void AddItem(ref ThreadPoolWorkItem Item) { CheckIfStartThread(); if (Interlocked.Increment(ref _RequestInQueue) == 1) { _DataInQueue.Set(); } _RequestQueue.Enqueue(Item); } // Work Thread main function internal void WorkerThread() { bool bWaitForData = true; while (true) { if (bWaitForData) { if (!_DataInQueue.WaitOne(_ThreadTimeout, false)) { // timeout RemoveThread(); return; } } Interlocked.Increment(ref _ThreadsInUse); try { ThreadPoolWorkItem oItem = (ThreadPoolWorkItem) _RequestQueue.Dequeue(); if (Interlocked.Decrement(ref _RequestInQueue) == 0) { _DataInQueue.Reset(); } oItem._CallBack(oItem._Context); } catch (InvalidOperationException) { // Queue empty bWaitForData = true; } catch (ThreadAbortException) { // We will leave here.. (thread abort can't be handled) RemoveThread(); } finally { Interlocked.Decrement(ref _ThreadsInUse); } } } internal void MonitorThread() { while (true) { Thread.Sleep(500); CheckIfStartThread(); } } internal bool QueueUserWorkItemInternal(WaitCallback callback) { return QueueUserWorkItem(callback, null); } internal bool QueueUserWorkItemInternal(WaitCallback callback, object context) { ThreadPoolWorkItem Item = new ThreadPoolWorkItem(); Item._CallBack = callback; Item._Context = context; AddItem(ref Item); // LAMESPEC: Return value? should use exception here if anything goes wrong return true; } public static bool BindHandle(IntPtr osHandle) { throw new NotSupportedException("This is a win32 specific method, not supported Mono"); } public static bool QueueUserWorkItem(WaitCallback callback) { return _Threadpool.QueueUserWorkItemInternal(callback); } public static bool QueueUserWorkItem(WaitCallback callback, object state) { return _Threadpool.QueueUserWorkItemInternal(callback, state); } public static bool UnsafeQueueUserWorkItem(WaitCallback callback, object state) { return _Threadpool.QueueUserWorkItemInternal(callback, state); } [MonoTODO] public static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, int millisecondsTimeOutInterval, bool executeOnlyOnce) { if (millisecondsTimeOutInterval < -1) { throw new ArgumentOutOfRangeException("timeout < -1"); } throw new NotImplementedException(); } [MonoTODO] public static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, long millisecondsTimeOutInterval, bool executeOnlyOnce) { if (millisecondsTimeOutInterval < -1) { throw new ArgumentOutOfRangeException("timeout < -1"); } throw new NotImplementedException(); } [MonoTODO] public static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, TimeSpan timeout, bool executeOnlyOnce) { // LAMESPEC: I assume it means "timeout" when it says "millisecondsTimeOutInterval" if (timeout.Milliseconds < -1) { throw new ArgumentOutOfRangeException("timeout < -1"); } if (timeout.Milliseconds > Int32.MaxValue) { throw new NotSupportedException("timeout too large"); } throw new NotImplementedException(); } [CLSCompliant(false)][MonoTODO] public static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, uint millisecondsTimeOutInterval, bool executeOnlyOnce) { throw new NotImplementedException(); } [MonoTODO] public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, int millisecondsTimeOutInterval, bool executeOnlyOnce) { throw new NotImplementedException(); } [MonoTODO] public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, long millisecondsTimeOutInterval, bool executeOnlyOnce) { throw new NotImplementedException(); } [MonoTODO] public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, TimeSpan timeout, bool executeOnlyOnce) { throw new NotImplementedException(); } [CLSCompliant(false)][MonoTODO] public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject, WaitOrTimerCallback callback, object state, uint millisecondsTimeOutInterval, bool executeOnlyOnce) { throw new NotImplementedException(); } } }