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