External/Aga.Controls/Threading/AbortableThreadPool.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
     1 // Stephen Toub
     2 // stoub@microsoft.com
     3 
     4 using System;
     5 using System.Collections.Generic;
     6 using System.Text;
     7 using System.Threading;
     8 
     9 namespace Aga.Controls.Threading
    10 {
    11 	public class AbortableThreadPool
    12 	{
    13 		private LinkedList<WorkItem> _callbacks = new LinkedList<WorkItem>();
    14 		private Dictionary<WorkItem, Thread> _threads = new Dictionary<WorkItem, Thread>();
    15 
    16 		public WorkItem QueueUserWorkItem(WaitCallback callback)
    17 		{
    18 			return QueueUserWorkItem(callback, null);
    19 		}
    20 
    21 		public WorkItem QueueUserWorkItem(WaitCallback callback, object state)
    22 		{
    23 			if (callback == null) throw new ArgumentNullException("callback");
    24 
    25 			WorkItem item = new WorkItem(callback, state, ExecutionContext.Capture());
    26 			lock (_callbacks)
    27 			{
    28 				_callbacks.AddLast(item);
    29 			}
    30 			ThreadPool.QueueUserWorkItem(new WaitCallback(HandleItem));
    31 			return item;
    32 		}
    33 
    34 		private void HandleItem(object ignored)
    35 		{
    36 			WorkItem item = null;
    37 			try
    38 			{
    39 				lock (_callbacks)
    40 				{
    41 					if (_callbacks.Count > 0)
    42 					{
    43 						item = _callbacks.First.Value;
    44 						_callbacks.RemoveFirst();
    45 					}
    46 					if (item == null)
    47 						return;
    48 					_threads.Add(item, Thread.CurrentThread);
    49 
    50 				}
    51 				ExecutionContext.Run(item.Context,
    52 					delegate { item.Callback(item.State); }, null);
    53 			}
    54 			finally
    55 			{
    56 				lock (_callbacks)
    57 				{
    58 					if (item != null)
    59 						_threads.Remove(item);
    60 				}
    61 			}
    62 		}
    63 
    64 		public bool IsMyThread(Thread thread)
    65 		{
    66 			lock (_callbacks)
    67 			{
    68 				foreach (Thread t in _threads.Values)
    69 				{
    70 					if (t == thread)
    71 						return true;
    72 				}
    73 				return false;
    74 			}
    75 		}
    76 
    77 		public WorkItemStatus Cancel(WorkItem item, bool allowAbort)
    78 		{
    79 			if (item == null)
    80 				throw new ArgumentNullException("item");
    81 			lock (_callbacks)
    82 			{
    83 				LinkedListNode<WorkItem> node = _callbacks.Find(item);
    84 				if (node != null)
    85 				{
    86 					_callbacks.Remove(node);
    87 					return WorkItemStatus.Queued;
    88 				}
    89 				else if (_threads.ContainsKey(item))
    90 				{
    91 					if (allowAbort)
    92 					{
    93 						_threads[item].Abort();
    94 						_threads.Remove(item);
    95 						return WorkItemStatus.Aborted;
    96 					}
    97 					else
    98 						return WorkItemStatus.Executing;
    99 				}
   100 				else
   101 					return WorkItemStatus.Completed;
   102 			}
   103 		}
   104 
   105 		public void CancelAll(bool allowAbort)
   106 		{
   107 			lock (_callbacks)
   108 			{
   109 				_callbacks.Clear();
   110 				if (allowAbort)
   111 				{
   112 					foreach (Thread t in _threads.Values)
   113 						t.Abort();
   114 				}
   115 			}
   116 		}
   117 	}
   118 }