aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ThirdParty
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ThirdParty/SmartThreadPool/CallerThreadContext.cs138
-rw-r--r--ThirdParty/SmartThreadPool/CanceledWorkItemsGroup.cs14
-rw-r--r--ThirdParty/SmartThreadPool/EventWaitHandle.cs104
-rw-r--r--ThirdParty/SmartThreadPool/EventWaitHandleFactory.cs82
-rw-r--r--ThirdParty/SmartThreadPool/Exceptions.cs111
-rw-r--r--ThirdParty/SmartThreadPool/Interfaces.cs628
-rw-r--r--ThirdParty/SmartThreadPool/InternalInterfaces.cs27
-rw-r--r--ThirdParty/SmartThreadPool/PriorityQueue.cs239
-rw-r--r--ThirdParty/SmartThreadPool/Properties/AssemblyInfo.cs23
-rw-r--r--ThirdParty/SmartThreadPool/SLExt.cs16
-rw-r--r--ThirdParty/SmartThreadPool/STPEventWaitHandle.cs62
-rw-r--r--ThirdParty/SmartThreadPool/STPPerformanceCounter.cs448
-rw-r--r--ThirdParty/SmartThreadPool/STPStartInfo.cs212
-rw-r--r--ThirdParty/SmartThreadPool/SmartThreadPool.ThreadEntry.cs60
-rw-r--r--ThirdParty/SmartThreadPool/SmartThreadPool.cs1737
-rw-r--r--ThirdParty/SmartThreadPool/SynchronizedDictionary.cs89
-rw-r--r--ThirdParty/SmartThreadPool/WIGStartInfo.cs171
-rw-r--r--ThirdParty/SmartThreadPool/WorkItem.WorkItemResult.cs190
-rw-r--r--ThirdParty/SmartThreadPool/WorkItem.cs1002
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemFactory.cs343
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemInfo.cs69
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemResultTWrapper.cs128
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemsGroup.cs361
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs471
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemsQueue.cs646
-rw-r--r--ThirdPartyLicenses/Aurora-Sim.txt26
-rw-r--r--ThirdPartyLicenses/Axiom.txt141
-rw-r--r--ThirdPartyLicenses/BclExtras.txt60
-rw-r--r--ThirdPartyLicenses/Bullet for Xna (ModifiedBulletX).txt19
-rw-r--r--ThirdPartyLicenses/Bullet-XNA.txt23
-rw-r--r--ThirdPartyLicenses/BulletLicense.txt17
-rw-r--r--ThirdPartyLicenses/C# Webserver.txt71
-rw-r--r--ThirdPartyLicenses/C5.txt19
-rw-r--r--ThirdPartyLicenses/CSCompilerTools.txt12
-rw-r--r--ThirdPartyLicenses/CSJ2K.txt28
-rw-r--r--ThirdPartyLicenses/CircularBuffer.txt16
-rw-r--r--ThirdPartyLicenses/ConvexDecompositionDotNet.txt28
-rw-r--r--ThirdPartyLicenses/DefaultTerrain.txt23
-rw-r--r--ThirdPartyLicenses/DotNetOpenid.txt10
-rw-r--r--ThirdPartyLicenses/DotNetZip-bzip2.txt29
-rw-r--r--ThirdPartyLicenses/DotNetZip-zlib.txt70
-rw-r--r--ThirdPartyLicenses/DotNetZip.txt33
-rw-r--r--ThirdPartyLicenses/GTCache.txt477
-rw-r--r--ThirdPartyLicenses/GoogleProtoBuffer.txt31
-rw-r--r--ThirdPartyLicenses/ICSharpCode.SharpZipLib.license.txt17
-rw-r--r--ThirdPartyLicenses/MXP.txt15
-rw-r--r--ThirdPartyLicenses/Mono.Xna (MonoXnaCompactMaths).txt22
-rw-r--r--ThirdPartyLicenses/MonoAddins.txt41
-rw-r--r--ThirdPartyLicenses/MySQL.txt122
-rw-r--r--ThirdPartyLicenses/Nini.txt23
-rw-r--r--ThirdPartyLicenses/Npgsql.txt7
-rw-r--r--ThirdPartyLicenses/ODE.txt13
-rw-r--r--ThirdPartyLicenses/OpenJpeg.txt30
-rw-r--r--ThirdPartyLicenses/Protobuf-net.txt21
-rw-r--r--ThirdPartyLicenses/Prototype.txt16
-rw-r--r--ThirdPartyLicenses/SmartThreadPool.txt22
-rw-r--r--ThirdPartyLicenses/XML-RPC.NET.txt27
-rw-r--r--ThirdPartyLicenses/libsl.txt23
58 files changed, 8903 insertions, 0 deletions
diff --git a/ThirdParty/SmartThreadPool/CallerThreadContext.cs b/ThirdParty/SmartThreadPool/CallerThreadContext.cs
new file mode 100644
index 0000000..925c39b
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/CallerThreadContext.cs
@@ -0,0 +1,138 @@
1
2#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
3
4using System;
5using System.Diagnostics;
6using System.Threading;
7using System.Reflection;
8using System.Web;
9using System.Runtime.Remoting.Messaging;
10
11
12namespace Amib.Threading.Internal
13{
14#region CallerThreadContext class
15
16 /// <summary>
17 /// This class stores the caller call context in order to restore
18 /// it when the work item is executed in the thread pool environment.
19 /// </summary>
20 internal class CallerThreadContext
21 {
22#region Prepare reflection information
23
24 // Cached type information.
25 private static readonly MethodInfo getLogicalCallContextMethodInfo =
26 typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
27
28 private static readonly MethodInfo setLogicalCallContextMethodInfo =
29 typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
30
31 private static string HttpContextSlotName = GetHttpContextSlotName();
32
33 private static string GetHttpContextSlotName()
34 {
35 FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
36
37 if (fi != null)
38 {
39 return (string) fi.GetValue(null);
40 }
41
42 return "HttpContext";
43 }
44
45 #endregion
46
47#region Private fields
48
49 private HttpContext _httpContext;
50 private LogicalCallContext _callContext;
51
52 #endregion
53
54 /// <summary>
55 /// Constructor
56 /// </summary>
57 private CallerThreadContext()
58 {
59 }
60
61 public bool CapturedCallContext
62 {
63 get
64 {
65 return (null != _callContext);
66 }
67 }
68
69 public bool CapturedHttpContext
70 {
71 get
72 {
73 return (null != _httpContext);
74 }
75 }
76
77 /// <summary>
78 /// Captures the current thread context
79 /// </summary>
80 /// <returns></returns>
81 public static CallerThreadContext Capture(
82 bool captureCallContext,
83 bool captureHttpContext)
84 {
85 Debug.Assert(captureCallContext || captureHttpContext);
86
87 CallerThreadContext callerThreadContext = new CallerThreadContext();
88
89 // TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture()
90 // Capture Call Context
91 if(captureCallContext && (getLogicalCallContextMethodInfo != null))
92 {
93 callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null);
94 if (callerThreadContext._callContext != null)
95 {
96 callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone();
97 }
98 }
99
100 // Capture httpContext
101 if (captureHttpContext && (null != HttpContext.Current))
102 {
103 callerThreadContext._httpContext = HttpContext.Current;
104 }
105
106 return callerThreadContext;
107 }
108
109 /// <summary>
110 /// Applies the thread context stored earlier
111 /// </summary>
112 /// <param name="callerThreadContext"></param>
113 public static void Apply(CallerThreadContext callerThreadContext)
114 {
115 if (null == callerThreadContext)
116 {
117 throw new ArgumentNullException("callerThreadContext");
118 }
119
120 // Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run()
121 // Restore call context
122 if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null))
123 {
124 setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext });
125 }
126
127 // Restore HttpContext
128 if (callerThreadContext._httpContext != null)
129 {
130 HttpContext.Current = callerThreadContext._httpContext;
131 //CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
132 }
133 }
134 }
135
136 #endregion
137}
138#endif
diff --git a/ThirdParty/SmartThreadPool/CanceledWorkItemsGroup.cs b/ThirdParty/SmartThreadPool/CanceledWorkItemsGroup.cs
new file mode 100644
index 0000000..5752957
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/CanceledWorkItemsGroup.cs
@@ -0,0 +1,14 @@
1namespace Amib.Threading.Internal
2{
3 internal class CanceledWorkItemsGroup
4 {
5 public readonly static CanceledWorkItemsGroup NotCanceledWorkItemsGroup = new CanceledWorkItemsGroup();
6
7 public CanceledWorkItemsGroup()
8 {
9 IsCanceled = false;
10 }
11
12 public bool IsCanceled { get; set; }
13 }
14} \ No newline at end of file
diff --git a/ThirdParty/SmartThreadPool/EventWaitHandle.cs b/ThirdParty/SmartThreadPool/EventWaitHandle.cs
new file mode 100644
index 0000000..b7983cd
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/EventWaitHandle.cs
@@ -0,0 +1,104 @@
1#if (_WINDOWS_CE)
2
3using System;
4using System.Runtime.InteropServices;
5using System.Threading;
6
7namespace Amib.Threading.Internal
8{
9 /// <summary>
10 /// EventWaitHandle class
11 /// In WindowsCE this class doesn't exist and I needed the WaitAll and WaitAny implementation.
12 /// So I wrote this class to implement these two methods with some of their overloads.
13 /// It uses the WaitForMultipleObjects API to do the WaitAll and WaitAny.
14 /// Note that this class doesn't even inherit from WaitHandle!
15 /// </summary>
16 public class STPEventWaitHandle
17 {
18 #region Public Constants
19
20 public const int WaitTimeout = Timeout.Infinite;
21
22 #endregion
23
24 #region Private External Constants
25
26 private const Int32 WAIT_FAILED = -1;
27 private const Int32 WAIT_TIMEOUT = 0x102;
28 private const UInt32 INFINITE = 0xFFFFFFFF;
29
30 #endregion
31
32 #region WaitAll and WaitAny
33
34 internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
35 {
36 return waitHandle.WaitOne(millisecondsTimeout, exitContext);
37 }
38
39 private static IntPtr[] PrepareNativeHandles(WaitHandle[] waitHandles)
40 {
41 IntPtr[] nativeHandles = new IntPtr[waitHandles.Length];
42 for (int i = 0; i < waitHandles.Length; i++)
43 {
44 nativeHandles[i] = waitHandles[i].Handle;
45 }
46 return nativeHandles;
47 }
48
49 public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
50 {
51 uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
52
53 IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles);
54
55 int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, true, timeout);
56
57 if (result == WAIT_TIMEOUT || result == WAIT_FAILED)
58 {
59 return false;
60 }
61
62 return true;
63 }
64
65
66 public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
67 {
68 uint timeout = millisecondsTimeout < 0 ? INFINITE : (uint)millisecondsTimeout;
69
70 IntPtr[] nativeHandles = PrepareNativeHandles(waitHandles);
71
72 int result = WaitForMultipleObjects((uint)waitHandles.Length, nativeHandles, false, timeout);
73
74 if (result >= 0 && result < waitHandles.Length)
75 {
76 return result;
77 }
78
79 return -1;
80 }
81
82 public static int WaitAny(WaitHandle[] waitHandles)
83 {
84 return WaitAny(waitHandles, Timeout.Infinite, false);
85 }
86
87 public static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext)
88 {
89 int millisecondsTimeout = (int)timeout.TotalMilliseconds;
90
91 return WaitAny(waitHandles, millisecondsTimeout, false);
92 }
93
94 #endregion
95
96 #region External methods
97
98 [DllImport("coredll.dll", SetLastError = true)]
99 public static extern int WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool fWaitAll, uint dwMilliseconds);
100
101 #endregion
102 }
103}
104#endif \ No newline at end of file
diff --git a/ThirdParty/SmartThreadPool/EventWaitHandleFactory.cs b/ThirdParty/SmartThreadPool/EventWaitHandleFactory.cs
new file mode 100644
index 0000000..ece24de
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/EventWaitHandleFactory.cs
@@ -0,0 +1,82 @@
1using System.Threading;
2
3#if (_WINDOWS_CE)
4using System;
5using System.Runtime.InteropServices;
6#endif
7
8namespace Amib.Threading.Internal
9{
10 /// <summary>
11 /// EventWaitHandleFactory class.
12 /// This is a static class that creates AutoResetEvent and ManualResetEvent objects.
13 /// In WindowCE the WaitForMultipleObjects API fails to use the Handle property
14 /// of XxxResetEvent. It can use only handles that were created by the CreateEvent API.
15 /// Consequently this class creates the needed XxxResetEvent and replaces the handle if
16 /// it's a WindowsCE OS.
17 /// </summary>
18 public static class EventWaitHandleFactory
19 {
20 /// <summary>
21 /// Create a new AutoResetEvent object
22 /// </summary>
23 /// <returns>Return a new AutoResetEvent object</returns>
24 public static AutoResetEvent CreateAutoResetEvent()
25 {
26 AutoResetEvent waitHandle = new AutoResetEvent(false);
27
28#if (_WINDOWS_CE)
29 ReplaceEventHandle(waitHandle, false, false);
30#endif
31
32 return waitHandle;
33 }
34
35 /// <summary>
36 /// Create a new ManualResetEvent object
37 /// </summary>
38 /// <returns>Return a new ManualResetEvent object</returns>
39 public static ManualResetEvent CreateManualResetEvent(bool initialState)
40 {
41 ManualResetEvent waitHandle = new ManualResetEvent(initialState);
42
43#if (_WINDOWS_CE)
44 ReplaceEventHandle(waitHandle, true, initialState);
45#endif
46
47 return waitHandle;
48 }
49
50#if (_WINDOWS_CE)
51
52 /// <summary>
53 /// Replace the event handle
54 /// </summary>
55 /// <param name="waitHandle">The WaitHandle object which its handle needs to be replaced.</param>
56 /// <param name="manualReset">Indicates if the event is a ManualResetEvent (true) or an AutoResetEvent (false)</param>
57 /// <param name="initialState">The initial state of the event</param>
58 private static void ReplaceEventHandle(WaitHandle waitHandle, bool manualReset, bool initialState)
59 {
60 // Store the old handle
61 IntPtr oldHandle = waitHandle.Handle;
62
63 // Create a new event
64 IntPtr newHandle = CreateEvent(IntPtr.Zero, manualReset, initialState, null);
65
66 // Replace the old event with the new event
67 waitHandle.Handle = newHandle;
68
69 // Close the old event
70 CloseHandle (oldHandle);
71 }
72
73 [DllImport("coredll.dll", SetLastError = true)]
74 public static extern IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);
75
76 //Handle
77 [DllImport("coredll.dll", SetLastError = true)]
78 public static extern bool CloseHandle(IntPtr hObject);
79#endif
80
81 }
82}
diff --git a/ThirdParty/SmartThreadPool/Exceptions.cs b/ThirdParty/SmartThreadPool/Exceptions.cs
new file mode 100644
index 0000000..6c6a88b
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/Exceptions.cs
@@ -0,0 +1,111 @@
1using System;
2#if !(_WINDOWS_CE)
3using System.Runtime.Serialization;
4#endif
5
6namespace Amib.Threading
7{
8 #region Exceptions
9
10 /// <summary>
11 /// Represents an exception in case IWorkItemResult.GetResult has been canceled
12 /// </summary>
13 public sealed partial class WorkItemCancelException : Exception
14 {
15 public WorkItemCancelException()
16 {
17 }
18
19 public WorkItemCancelException(string message)
20 : base(message)
21 {
22 }
23
24 public WorkItemCancelException(string message, Exception e)
25 : base(message, e)
26 {
27 }
28 }
29
30 /// <summary>
31 /// Represents an exception in case IWorkItemResult.GetResult has been timed out
32 /// </summary>
33 public sealed partial class WorkItemTimeoutException : Exception
34 {
35 public WorkItemTimeoutException()
36 {
37 }
38
39 public WorkItemTimeoutException(string message)
40 : base(message)
41 {
42 }
43
44 public WorkItemTimeoutException(string message, Exception e)
45 : base(message, e)
46 {
47 }
48 }
49
50 /// <summary>
51 /// Represents an exception in case IWorkItemResult.GetResult has been timed out
52 /// </summary>
53 public sealed partial class WorkItemResultException : Exception
54 {
55 public WorkItemResultException()
56 {
57 }
58
59 public WorkItemResultException(string message)
60 : base(message)
61 {
62 }
63
64 public WorkItemResultException(string message, Exception e)
65 : base(message, e)
66 {
67 }
68 }
69
70
71#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
72 /// <summary>
73 /// Represents an exception in case IWorkItemResult.GetResult has been canceled
74 /// </summary>
75 [Serializable]
76 public sealed partial class WorkItemCancelException
77 {
78 public WorkItemCancelException(SerializationInfo si, StreamingContext sc)
79 : base(si, sc)
80 {
81 }
82 }
83
84 /// <summary>
85 /// Represents an exception in case IWorkItemResult.GetResult has been timed out
86 /// </summary>
87 [Serializable]
88 public sealed partial class WorkItemTimeoutException
89 {
90 public WorkItemTimeoutException(SerializationInfo si, StreamingContext sc)
91 : base(si, sc)
92 {
93 }
94 }
95
96 /// <summary>
97 /// Represents an exception in case IWorkItemResult.GetResult has been timed out
98 /// </summary>
99 [Serializable]
100 public sealed partial class WorkItemResultException
101 {
102 public WorkItemResultException(SerializationInfo si, StreamingContext sc)
103 : base(si, sc)
104 {
105 }
106 }
107
108#endif
109
110 #endregion
111}
diff --git a/ThirdParty/SmartThreadPool/Interfaces.cs b/ThirdParty/SmartThreadPool/Interfaces.cs
new file mode 100644
index 0000000..8cc23a0
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/Interfaces.cs
@@ -0,0 +1,628 @@
1using System;
2using System.Threading;
3
4namespace Amib.Threading
5{
6 #region Delegates
7
8 /// <summary>
9 /// A delegate that represents the method to run as the work item
10 /// </summary>
11 /// <param name="state">A state object for the method to run</param>
12 public delegate object WorkItemCallback(object state);
13
14 /// <summary>
15 /// A delegate to call after the WorkItemCallback completed
16 /// </summary>
17 /// <param name="wir">The work item result object</param>
18 public delegate void PostExecuteWorkItemCallback(IWorkItemResult wir);
19
20 /// <summary>
21 /// A delegate to call after the WorkItemCallback completed
22 /// </summary>
23 /// <param name="wir">The work item result object</param>
24 public delegate void PostExecuteWorkItemCallback<TResult>(IWorkItemResult<TResult> wir);
25
26 /// <summary>
27 /// A delegate to call when a WorkItemsGroup becomes idle
28 /// </summary>
29 /// <param name="workItemsGroup">A reference to the WorkItemsGroup that became idle</param>
30 public delegate void WorkItemsGroupIdleHandler(IWorkItemsGroup workItemsGroup);
31
32 /// <summary>
33 /// A delegate to call after a thread is created, but before
34 /// it's first use.
35 /// </summary>
36 public delegate void ThreadInitializationHandler();
37
38 /// <summary>
39 /// A delegate to call when a thread is about to exit, after
40 /// it is no longer belong to the pool.
41 /// </summary>
42 public delegate void ThreadTerminationHandler();
43
44 #endregion
45
46 #region WorkItem Priority
47
48 /// <summary>
49 /// Defines the availeable priorities of a work item.
50 /// The higher the priority a work item has, the sooner
51 /// it will be executed.
52 /// </summary>
53 public enum WorkItemPriority
54 {
55 Lowest,
56 BelowNormal,
57 Normal,
58 AboveNormal,
59 Highest,
60 }
61
62 #endregion
63
64 #region IWorkItemsGroup interface
65
66 /// <summary>
67 /// IWorkItemsGroup interface
68 /// Created by SmartThreadPool.CreateWorkItemsGroup()
69 /// </summary>
70 public interface IWorkItemsGroup
71 {
72 /// <summary>
73 /// Get/Set the name of the WorkItemsGroup
74 /// </summary>
75 string Name { get; set; }
76
77 /// <summary>
78 /// Get/Set the maximum number of workitem that execute cocurrency on the thread pool
79 /// </summary>
80 int Concurrency { get; set; }
81
82 /// <summary>
83 /// Get the number of work items waiting in the queue.
84 /// </summary>
85 int WaitingCallbacks { get; }
86
87 /// <summary>
88 /// Get an array with all the state objects of the currently running items.
89 /// The array represents a snap shot and impact performance.
90 /// </summary>
91 object[] GetStates();
92
93 /// <summary>
94 /// Get the WorkItemsGroup start information
95 /// </summary>
96 WIGStartInfo WIGStartInfo { get; }
97
98 /// <summary>
99 /// Starts to execute work items
100 /// </summary>
101 void Start();
102
103 /// <summary>
104 /// Cancel all the work items.
105 /// Same as Cancel(false)
106 /// </summary>
107 void Cancel();
108
109 /// <summary>
110 /// Cancel all work items using thread abortion
111 /// </summary>
112 /// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param>
113 void Cancel(bool abortExecution);
114
115 /// <summary>
116 /// Wait for all work item to complete.
117 /// </summary>
118 void WaitForIdle();
119
120 /// <summary>
121 /// Wait for all work item to complete, until timeout expired
122 /// </summary>
123 /// <param name="timeout">How long to wait for the work items to complete</param>
124 /// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
125 bool WaitForIdle(TimeSpan timeout);
126
127 /// <summary>
128 /// Wait for all work item to complete, until timeout expired
129 /// </summary>
130 /// <param name="millisecondsTimeout">How long to wait for the work items to complete in milliseconds</param>
131 /// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
132 bool WaitForIdle(int millisecondsTimeout);
133
134 /// <summary>
135 /// IsIdle is true when there are no work items running or queued.
136 /// </summary>
137 bool IsIdle { get; }
138
139 /// <summary>
140 /// This event is fired when all work items are completed.
141 /// (When IsIdle changes to true)
142 /// This event only work on WorkItemsGroup. On SmartThreadPool
143 /// it throws the NotImplementedException.
144 /// </summary>
145 event WorkItemsGroupIdleHandler OnIdle;
146
147 #region QueueWorkItem
148
149 /// <summary>
150 /// Queue a work item
151 /// </summary>
152 /// <param name="callback">A callback to execute</param>
153 /// <returns>Returns a work item result</returns>
154 IWorkItemResult QueueWorkItem(WorkItemCallback callback);
155
156 /// <summary>
157 /// Queue a work item
158 /// </summary>
159 /// <param name="callback">A callback to execute</param>
160 /// <param name="workItemPriority">The priority of the work item</param>
161 /// <returns>Returns a work item result</returns>
162 IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority);
163
164 /// <summary>
165 /// Queue a work item
166 /// </summary>
167 /// <param name="callback">A callback to execute</param>
168 /// <param name="state">
169 /// The context object of the work item. Used for passing arguments to the work item.
170 /// </param>
171 /// <returns>Returns a work item result</returns>
172 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
173
174 /// <summary>
175 /// Queue a work item
176 /// </summary>
177 /// <param name="callback">A callback to execute</param>
178 /// <param name="state">
179 /// The context object of the work item. Used for passing arguments to the work item.
180 /// </param>
181 /// <param name="workItemPriority">The work item priority</param>
182 /// <returns>Returns a work item result</returns>
183 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority);
184
185 /// <summary>
186 /// Queue a work item
187 /// </summary>
188 /// <param name="callback">A callback to execute</param>
189 /// <param name="state">
190 /// The context object of the work item. Used for passing arguments to the work item.
191 /// </param>
192 /// <param name="postExecuteWorkItemCallback">
193 /// A delegate to call after the callback completion
194 /// </param>
195 /// <returns>Returns a work item result</returns>
196 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
197
198 /// <summary>
199 /// Queue a work item
200 /// </summary>
201 /// <param name="callback">A callback to execute</param>
202 /// <param name="state">
203 /// The context object of the work item. Used for passing arguments to the work item.
204 /// </param>
205 /// <param name="postExecuteWorkItemCallback">
206 /// A delegate to call after the callback completion
207 /// </param>
208 /// <param name="workItemPriority">The work item priority</param>
209 /// <returns>Returns a work item result</returns>
210 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority);
211
212 /// <summary>
213 /// Queue a work item
214 /// </summary>
215 /// <param name="callback">A callback to execute</param>
216 /// <param name="state">
217 /// The context object of the work item. Used for passing arguments to the work item.
218 /// </param>
219 /// <param name="postExecuteWorkItemCallback">
220 /// A delegate to call after the callback completion
221 /// </param>
222 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
223 /// <returns>Returns a work item result</returns>
224 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
225
226 /// <summary>
227 /// Queue a work item
228 /// </summary>
229 /// <param name="callback">A callback to execute</param>
230 /// <param name="state">
231 /// The context object of the work item. Used for passing arguments to the work item.
232 /// </param>
233 /// <param name="postExecuteWorkItemCallback">
234 /// A delegate to call after the callback completion
235 /// </param>
236 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
237 /// <param name="workItemPriority">The work item priority</param>
238 /// <returns>Returns a work item result</returns>
239 IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority);
240
241 /// <summary>
242 /// Queue a work item
243 /// </summary>
244 /// <param name="workItemInfo">Work item info</param>
245 /// <param name="callback">A callback to execute</param>
246 /// <returns>Returns a work item result</returns>
247 IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
248
249 /// <summary>
250 /// Queue a work item
251 /// </summary>
252 /// <param name="workItemInfo">Work item information</param>
253 /// <param name="callback">A callback to execute</param>
254 /// <param name="state">
255 /// The context object of the work item. Used for passing arguments to the work item.
256 /// </param>
257 /// <returns>Returns a work item result</returns>
258 IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);
259
260 #endregion
261
262 #region QueueWorkItem(Action<...>)
263
264 /// <summary>
265 /// Queue a work item.
266 /// </summary>
267 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
268 IWorkItemResult QueueWorkItem(Action action);
269
270 /// <summary>
271 /// Queue a work item.
272 /// </summary>
273 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
274 IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority);
275
276 /// <summary>
277 /// Queue a work item.
278 /// </summary>
279 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
280 IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority);
281
282 /// <summary>
283 /// Queue a work item.
284 /// </summary>
285 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
286 IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg);
287
288 /// <summary>
289 /// Queue a work item.
290 /// </summary>
291 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
292 IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2);
293
294 /// <summary>
295 /// Queue a work item.
296 /// </summary>
297 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
298 IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority);
299
300 /// <summary>
301 /// Queue a work item.
302 /// </summary>
303 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
304 IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3);
305
306 /// <summary>
307 /// Queue a work item.
308 /// </summary>
309 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
310 IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority);
311
312 /// <summary>
313 /// Queue a work item.
314 /// </summary>
315 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
316 IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
317
318 /// <summary>
319 /// Queue a work item.
320 /// </summary>
321 /// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
322 IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority);
323
324 #endregion
325
326 #region QueueWorkItem(Func<...>)
327
328 /// <summary>
329 /// Queue a work item.
330 /// </summary>
331 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
332 /// its GetResult() returns a TResult object</returns>
333 IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func);
334
335 /// <summary>
336 /// Queue a work item.
337 /// </summary>
338 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
339 /// its GetResult() returns a TResult object</returns>
340 IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg);
341
342 /// <summary>
343 /// Queue a work item.
344 /// </summary>
345 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
346 /// its GetResult() returns a TResult object</returns>
347 IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2);
348
349 /// <summary>
350 /// Queue a work item.
351 /// </summary>
352 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
353 /// its GetResult() returns a TResult object</returns>
354 IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3);
355
356 /// <summary>
357 /// Queue a work item.
358 /// </summary>
359 /// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
360 /// its GetResult() returns a TResult object</returns>
361 IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
362
363 #endregion
364 }
365
366 #endregion
367
368 #region CallToPostExecute enumerator
369
370 [Flags]
371 public enum CallToPostExecute
372 {
373 /// <summary>
374 /// Never call to the PostExecute call back
375 /// </summary>
376 Never = 0x00,
377
378 /// <summary>
379 /// Call to the PostExecute only when the work item is cancelled
380 /// </summary>
381 WhenWorkItemCanceled = 0x01,
382
383 /// <summary>
384 /// Call to the PostExecute only when the work item is not cancelled
385 /// </summary>
386 WhenWorkItemNotCanceled = 0x02,
387
388 /// <summary>
389 /// Always call to the PostExecute
390 /// </summary>
391 Always = WhenWorkItemCanceled | WhenWorkItemNotCanceled,
392 }
393
394 #endregion
395
396 #region IWorkItemResult interface
397
398 /// <summary>
399 /// The common interface of IWorkItemResult and IWorkItemResult&lt;T&gt;
400 /// </summary>
401 public interface IWaitableResult
402 {
403 /// <summary>
404 /// This method intent is for internal use.
405 /// </summary>
406 /// <returns></returns>
407 IWorkItemResult GetWorkItemResult();
408
409 /// <summary>
410 /// This method intent is for internal use.
411 /// </summary>
412 /// <returns></returns>
413 IWorkItemResult<TResult> GetWorkItemResultT<TResult>();
414 }
415
416 /// <summary>
417 /// IWorkItemResult interface.
418 /// Created when a WorkItemCallback work item is queued.
419 /// </summary>
420 public interface IWorkItemResult : IWorkItemResult<object>
421 {
422 }
423
424 /// <summary>
425 /// IWorkItemResult&lt;TResult&gt; interface.
426 /// Created when a Func&lt;TResult&gt; work item is queued.
427 /// </summary>
428 public interface IWorkItemResult<TResult> : IWaitableResult
429 {
430 /// <summary>
431 /// Get the result of the work item.
432 /// If the work item didn't run yet then the caller waits.
433 /// </summary>
434 /// <returns>The result of the work item</returns>
435 TResult GetResult();
436
437 /// <summary>
438 /// Get the result of the work item.
439 /// If the work item didn't run yet then the caller waits until timeout.
440 /// </summary>
441 /// <returns>The result of the work item</returns>
442 /// On timeout throws WorkItemTimeoutException
443 TResult GetResult(
444 int millisecondsTimeout,
445 bool exitContext);
446
447 /// <summary>
448 /// Get the result of the work item.
449 /// If the work item didn't run yet then the caller waits until timeout.
450 /// </summary>
451 /// <returns>The result of the work item</returns>
452 /// On timeout throws WorkItemTimeoutException
453 TResult GetResult(
454 TimeSpan timeout,
455 bool exitContext);
456
457 /// <summary>
458 /// Get the result of the work item.
459 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
460 /// </summary>
461 /// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
462 /// <param name="exitContext">
463 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
464 /// </param>
465 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
466 /// <returns>The result of the work item</returns>
467 /// On timeout throws WorkItemTimeoutException
468 /// On cancel throws WorkItemCancelException
469 TResult GetResult(
470 int millisecondsTimeout,
471 bool exitContext,
472 WaitHandle cancelWaitHandle);
473
474 /// <summary>
475 /// Get the result of the work item.
476 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
477 /// </summary>
478 /// <returns>The result of the work item</returns>
479 /// On timeout throws WorkItemTimeoutException
480 /// On cancel throws WorkItemCancelException
481 TResult GetResult(
482 TimeSpan timeout,
483 bool exitContext,
484 WaitHandle cancelWaitHandle);
485
486 /// <summary>
487 /// Get the result of the work item.
488 /// If the work item didn't run yet then the caller waits.
489 /// </summary>
490 /// <param name="e">Filled with the exception if one was thrown</param>
491 /// <returns>The result of the work item</returns>
492 TResult GetResult(out Exception e);
493
494 /// <summary>
495 /// Get the result of the work item.
496 /// If the work item didn't run yet then the caller waits until timeout.
497 /// </summary>
498 /// <param name="millisecondsTimeout"></param>
499 /// <param name="exitContext"></param>
500 /// <param name="e">Filled with the exception if one was thrown</param>
501 /// <returns>The result of the work item</returns>
502 /// On timeout throws WorkItemTimeoutException
503 TResult GetResult(
504 int millisecondsTimeout,
505 bool exitContext,
506 out Exception e);
507
508 /// <summary>
509 /// Get the result of the work item.
510 /// If the work item didn't run yet then the caller waits until timeout.
511 /// </summary>
512 /// <param name="exitContext"></param>
513 /// <param name="e">Filled with the exception if one was thrown</param>
514 /// <param name="timeout"></param>
515 /// <returns>The result of the work item</returns>
516 /// On timeout throws WorkItemTimeoutException
517 TResult GetResult(
518 TimeSpan timeout,
519 bool exitContext,
520 out Exception e);
521
522 /// <summary>
523 /// Get the result of the work item.
524 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
525 /// </summary>
526 /// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
527 /// <param name="exitContext">
528 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
529 /// </param>
530 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
531 /// <param name="e">Filled with the exception if one was thrown</param>
532 /// <returns>The result of the work item</returns>
533 /// On timeout throws WorkItemTimeoutException
534 /// On cancel throws WorkItemCancelException
535 TResult GetResult(
536 int millisecondsTimeout,
537 bool exitContext,
538 WaitHandle cancelWaitHandle,
539 out Exception e);
540
541 /// <summary>
542 /// Get the result of the work item.
543 /// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
544 /// </summary>
545 /// <returns>The result of the work item</returns>
546 /// <param name="cancelWaitHandle"></param>
547 /// <param name="e">Filled with the exception if one was thrown</param>
548 /// <param name="timeout"></param>
549 /// <param name="exitContext"></param>
550 /// On timeout throws WorkItemTimeoutException
551 /// On cancel throws WorkItemCancelException
552 TResult GetResult(
553 TimeSpan timeout,
554 bool exitContext,
555 WaitHandle cancelWaitHandle,
556 out Exception e);
557
558 /// <summary>
559 /// Gets an indication whether the asynchronous operation has completed.
560 /// </summary>
561 bool IsCompleted { get; }
562
563 /// <summary>
564 /// Gets an indication whether the asynchronous operation has been canceled.
565 /// </summary>
566 bool IsCanceled { get; }
567
568 /// <summary>
569 /// Gets the user-defined object that contains context data
570 /// for the work item method.
571 /// </summary>
572 object State { get; }
573
574 /// <summary>
575 /// Same as Cancel(false).
576 /// </summary>
577 bool Cancel();
578
579 /// <summary>
580 /// Cancel the work item execution.
581 /// If the work item is in the queue then it won't execute
582 /// If the work item is completed, it will remain completed
583 /// If the work item is in progress then the user can check the SmartThreadPool.IsWorkItemCanceled
584 /// property to check if the work item has been cancelled. If the abortExecution is set to true then
585 /// the Smart Thread Pool will send an AbortException to the running thread to stop the execution
586 /// of the work item. When an in progress work item is canceled its GetResult will throw WorkItemCancelException.
587 /// If the work item is already cancelled it will remain cancelled
588 /// </summary>
589 /// <param name="abortExecution">When true send an AbortException to the executing thread.</param>
590 /// <returns>Returns true if the work item was not completed, otherwise false.</returns>
591 bool Cancel(bool abortExecution);
592
593 /// <summary>
594 /// Get the work item's priority
595 /// </summary>
596 WorkItemPriority WorkItemPriority { get; }
597
598 /// <summary>
599 /// Return the result, same as GetResult()
600 /// </summary>
601 TResult Result { get; }
602
603 /// <summary>
604 /// Returns the exception if occured otherwise returns null.
605 /// </summary>
606 object Exception { get; }
607 }
608
609 #endregion
610
611 #region .NET 3.5
612
613 // All these delegate are built-in .NET 3.5
614 // Comment/Remove them when compiling to .NET 3.5 to avoid ambiguity.
615
616 public delegate void Action();
617 public delegate void Action<T1, T2>(T1 arg1, T2 arg2);
618 public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
619 public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
620
621 public delegate TResult Func<TResult>();
622 public delegate TResult Func<T, TResult>(T arg1);
623 public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
624 public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
625 public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
626
627 #endregion
628}
diff --git a/ThirdParty/SmartThreadPool/InternalInterfaces.cs b/ThirdParty/SmartThreadPool/InternalInterfaces.cs
new file mode 100644
index 0000000..3055117
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/InternalInterfaces.cs
@@ -0,0 +1,27 @@
1
2namespace Amib.Threading.Internal
3{
4 /// <summary>
5 /// An internal delegate to call when the WorkItem starts or completes
6 /// </summary>
7 internal delegate void WorkItemStateCallback(WorkItem workItem);
8
9 internal interface IInternalWorkItemResult
10 {
11 event WorkItemStateCallback OnWorkItemStarted;
12 event WorkItemStateCallback OnWorkItemCompleted;
13 }
14
15 internal interface IInternalWaitableResult
16 {
17 /// <summary>
18 /// This method is intent for internal use.
19 /// </summary>
20 IWorkItemResult GetWorkItemResult();
21 }
22
23 public interface IHasWorkItemPriority
24 {
25 WorkItemPriority WorkItemPriority { get; }
26 }
27}
diff --git a/ThirdParty/SmartThreadPool/PriorityQueue.cs b/ThirdParty/SmartThreadPool/PriorityQueue.cs
new file mode 100644
index 0000000..3ea6084
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/PriorityQueue.cs
@@ -0,0 +1,239 @@
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Diagnostics;
5
6namespace Amib.Threading.Internal
7{
8 #region PriorityQueue class
9
10 /// <summary>
11 /// PriorityQueue class
12 /// This class is not thread safe because we use external lock
13 /// </summary>
14 public sealed class PriorityQueue : IEnumerable
15 {
16 #region Private members
17
18 /// <summary>
19 /// The number of queues, there is one for each type of priority
20 /// </summary>
21 private const int _queuesCount = WorkItemPriority.Highest-WorkItemPriority.Lowest+1;
22
23 /// <summary>
24 /// Work items queues. There is one for each type of priority
25 /// </summary>
26 private readonly LinkedList<IHasWorkItemPriority>[] _queues = new LinkedList<IHasWorkItemPriority>[_queuesCount];
27
28 /// <summary>
29 /// The total number of work items within the queues
30 /// </summary>
31 private int _workItemsCount;
32
33 /// <summary>
34 /// Use with IEnumerable interface
35 /// </summary>
36 private int _version;
37
38 #endregion
39
40 #region Contructor
41
42 public PriorityQueue()
43 {
44 for(int i = 0; i < _queues.Length; ++i)
45 {
46 _queues[i] = new LinkedList<IHasWorkItemPriority>();
47 }
48 }
49
50 #endregion
51
52 #region Methods
53
54 /// <summary>
55 /// Enqueue a work item.
56 /// </summary>
57 /// <param name="workItem">A work item</param>
58 public void Enqueue(IHasWorkItemPriority workItem)
59 {
60 Debug.Assert(null != workItem);
61
62 int queueIndex = _queuesCount-(int)workItem.WorkItemPriority-1;
63 Debug.Assert(queueIndex >= 0);
64 Debug.Assert(queueIndex < _queuesCount);
65
66 _queues[queueIndex].AddLast(workItem);
67 ++_workItemsCount;
68 ++_version;
69 }
70
71 /// <summary>
72 /// Dequeque a work item.
73 /// </summary>
74 /// <returns>Returns the next work item</returns>
75 public IHasWorkItemPriority Dequeue()
76 {
77 IHasWorkItemPriority workItem = null;
78
79 if(_workItemsCount > 0)
80 {
81 int queueIndex = GetNextNonEmptyQueue(-1);
82 Debug.Assert(queueIndex >= 0);
83 workItem = _queues[queueIndex].First.Value;
84 _queues[queueIndex].RemoveFirst();
85 Debug.Assert(null != workItem);
86 --_workItemsCount;
87 ++_version;
88 }
89
90 return workItem;
91 }
92
93 /// <summary>
94 /// Find the next non empty queue starting at queue queueIndex+1
95 /// </summary>
96 /// <param name="queueIndex">The index-1 to start from</param>
97 /// <returns>
98 /// The index of the next non empty queue or -1 if all the queues are empty
99 /// </returns>
100 private int GetNextNonEmptyQueue(int queueIndex)
101 {
102 for(int i = queueIndex+1; i < _queuesCount; ++i)
103 {
104 if(_queues[i].Count > 0)
105 {
106 return i;
107 }
108 }
109 return -1;
110 }
111
112 /// <summary>
113 /// The number of work items
114 /// </summary>
115 public int Count
116 {
117 get
118 {
119 return _workItemsCount;
120 }
121 }
122
123 /// <summary>
124 /// Clear all the work items
125 /// </summary>
126 public void Clear()
127 {
128 if (_workItemsCount > 0)
129 {
130 foreach(LinkedList<IHasWorkItemPriority> queue in _queues)
131 {
132 queue.Clear();
133 }
134 _workItemsCount = 0;
135 ++_version;
136 }
137 }
138
139 #endregion
140
141 #region IEnumerable Members
142
143 /// <summary>
144 /// Returns an enumerator to iterate over the work items
145 /// </summary>
146 /// <returns>Returns an enumerator</returns>
147 public IEnumerator GetEnumerator()
148 {
149 return new PriorityQueueEnumerator(this);
150 }
151
152 #endregion
153
154 #region PriorityQueueEnumerator
155
156 /// <summary>
157 /// The class the implements the enumerator
158 /// </summary>
159 private class PriorityQueueEnumerator : IEnumerator
160 {
161 private readonly PriorityQueue _priorityQueue;
162 private int _version;
163 private int _queueIndex;
164 private IEnumerator _enumerator;
165
166 public PriorityQueueEnumerator(PriorityQueue priorityQueue)
167 {
168 _priorityQueue = priorityQueue;
169 _version = _priorityQueue._version;
170 _queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
171 if (_queueIndex >= 0)
172 {
173 _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
174 }
175 else
176 {
177 _enumerator = null;
178 }
179 }
180
181 #region IEnumerator Members
182
183 public void Reset()
184 {
185 _version = _priorityQueue._version;
186 _queueIndex = _priorityQueue.GetNextNonEmptyQueue(-1);
187 if (_queueIndex >= 0)
188 {
189 _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
190 }
191 else
192 {
193 _enumerator = null;
194 }
195 }
196
197 public object Current
198 {
199 get
200 {
201 Debug.Assert(null != _enumerator);
202 return _enumerator.Current;
203 }
204 }
205
206 public bool MoveNext()
207 {
208 if (null == _enumerator)
209 {
210 return false;
211 }
212
213 if(_version != _priorityQueue._version)
214 {
215 throw new InvalidOperationException("The collection has been modified");
216
217 }
218 if (!_enumerator.MoveNext())
219 {
220 _queueIndex = _priorityQueue.GetNextNonEmptyQueue(_queueIndex);
221 if(-1 == _queueIndex)
222 {
223 return false;
224 }
225 _enumerator = _priorityQueue._queues[_queueIndex].GetEnumerator();
226 _enumerator.MoveNext();
227 return true;
228 }
229 return true;
230 }
231
232 #endregion
233 }
234
235 #endregion
236 }
237
238 #endregion
239}
diff --git a/ThirdParty/SmartThreadPool/Properties/AssemblyInfo.cs b/ThirdParty/SmartThreadPool/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4728c1f
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/Properties/AssemblyInfo.cs
@@ -0,0 +1,23 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4
5[assembly: AssemblyTitle("Amib.Threading")]
6[assembly: AssemblyDescription("Smart Thread Pool")]
7[assembly: AssemblyConfiguration("")]
8[assembly: AssemblyCompany("")]
9[assembly: AssemblyProduct("Amib.Threading")]
10[assembly: AssemblyCopyright("")]
11[assembly: AssemblyTrademark("")]
12[assembly: AssemblyCulture("")]
13[assembly: ComVisible(false)]
14[assembly: Guid("c764a3de-c4f8-434d-85b5-a09830d1e44f")]
15[assembly: AssemblyVersion("2.2.3.0")]
16
17#if (_PUBLISH)
18[assembly: InternalsVisibleTo("STPTests,PublicKey=00240000048000009400000006020000002400005253413100040000010001004fe3d39add741ba7c8d52cd1eb0d94c7d79060ad956cbaff0e51c1dce94db10356b261778bc1ac3114b3218434da6fcd8416dd5507653809598f7d2afc422099ce4f6b7b0477f18e6c57c727ef2a7ab6ee56e6b4589fe44cb0e25f2875a3c65ab0383ee33c4dd93023f7ce1218bebc8b7a9a1dac878938f5c4f45ea74b6bd8ad")]
19#else
20[assembly: InternalsVisibleTo("STPTests")]
21#endif
22
23
diff --git a/ThirdParty/SmartThreadPool/SLExt.cs b/ThirdParty/SmartThreadPool/SLExt.cs
new file mode 100644
index 0000000..23a60bc
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/SLExt.cs
@@ -0,0 +1,16 @@
1#if _SILVERLIGHT
2
3using System.Threading;
4
5namespace Amib.Threading
6{
7 public enum ThreadPriority
8 {
9 Lowest,
10 BelowNormal,
11 Normal,
12 AboveNormal,
13 Highest,
14 }
15}
16#endif
diff --git a/ThirdParty/SmartThreadPool/STPEventWaitHandle.cs b/ThirdParty/SmartThreadPool/STPEventWaitHandle.cs
new file mode 100644
index 0000000..9b17f69
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/STPEventWaitHandle.cs
@@ -0,0 +1,62 @@
1#if !(_WINDOWS_CE)
2
3using System;
4using System.Threading;
5
6namespace Amib.Threading.Internal
7{
8#if _WINDOWS || WINDOWS_PHONE
9 internal static class STPEventWaitHandle
10 {
11 public const int WaitTimeout = Timeout.Infinite;
12
13 internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
14 {
15 return WaitHandle.WaitAll(waitHandles, millisecondsTimeout);
16 }
17
18 internal static int WaitAny(WaitHandle[] waitHandles)
19 {
20 return WaitHandle.WaitAny(waitHandles);
21 }
22
23 internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
24 {
25 return WaitHandle.WaitAny(waitHandles, millisecondsTimeout);
26 }
27
28 internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
29 {
30 return waitHandle.WaitOne(millisecondsTimeout);
31 }
32 }
33#else
34 internal static class STPEventWaitHandle
35 {
36 public const int WaitTimeout = Timeout.Infinite;
37
38 internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
39 {
40 return WaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext);
41 }
42
43 internal static int WaitAny(WaitHandle[] waitHandles)
44 {
45 return WaitHandle.WaitAny(waitHandles);
46 }
47
48 internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
49 {
50 return WaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);
51 }
52
53 internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
54 {
55 return waitHandle.WaitOne(millisecondsTimeout, exitContext);
56 }
57 }
58#endif
59
60}
61
62#endif \ No newline at end of file
diff --git a/ThirdParty/SmartThreadPool/STPPerformanceCounter.cs b/ThirdParty/SmartThreadPool/STPPerformanceCounter.cs
new file mode 100644
index 0000000..bd68499
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/STPPerformanceCounter.cs
@@ -0,0 +1,448 @@
1using System;
2using System.Diagnostics;
3using System.Threading;
4
5namespace Amib.Threading
6{
7 public interface ISTPPerformanceCountersReader
8 {
9 long InUseThreads { get; }
10 long ActiveThreads { get; }
11 long WorkItemsQueued { get; }
12 long WorkItemsProcessed { get; }
13 }
14}
15
16namespace Amib.Threading.Internal
17{
18 internal interface ISTPInstancePerformanceCounters : IDisposable
19 {
20 void Close();
21 void SampleThreads(long activeThreads, long inUseThreads);
22 void SampleWorkItems(long workItemsQueued, long workItemsProcessed);
23 void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime);
24 void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime);
25 }
26#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
27
28 internal enum STPPerformanceCounterType
29 {
30 // Fields
31 ActiveThreads = 0,
32 InUseThreads = 1,
33 OverheadThreads = 2,
34 OverheadThreadsPercent = 3,
35 OverheadThreadsPercentBase = 4,
36
37 WorkItems = 5,
38 WorkItemsInQueue = 6,
39 WorkItemsProcessed = 7,
40
41 WorkItemsQueuedPerSecond = 8,
42 WorkItemsProcessedPerSecond = 9,
43
44 AvgWorkItemWaitTime = 10,
45 AvgWorkItemWaitTimeBase = 11,
46
47 AvgWorkItemProcessTime = 12,
48 AvgWorkItemProcessTimeBase = 13,
49
50 WorkItemsGroups = 14,
51
52 LastCounter = 14,
53 }
54
55
56 /// <summary>
57 /// Summary description for STPPerformanceCounter.
58 /// </summary>
59 internal class STPPerformanceCounter
60 {
61 // Fields
62 private readonly PerformanceCounterType _pcType;
63 protected string _counterHelp;
64 protected string _counterName;
65
66 // Methods
67 public STPPerformanceCounter(
68 string counterName,
69 string counterHelp,
70 PerformanceCounterType pcType)
71 {
72 _counterName = counterName;
73 _counterHelp = counterHelp;
74 _pcType = pcType;
75 }
76
77 public void AddCounterToCollection(CounterCreationDataCollection counterData)
78 {
79 CounterCreationData counterCreationData = new CounterCreationData(
80 _counterName,
81 _counterHelp,
82 _pcType);
83
84 counterData.Add(counterCreationData);
85 }
86
87 // Properties
88 public string Name
89 {
90 get
91 {
92 return _counterName;
93 }
94 }
95 }
96
97 internal class STPPerformanceCounters
98 {
99 // Fields
100 internal STPPerformanceCounter[] _stpPerformanceCounters;
101 private static readonly STPPerformanceCounters _instance;
102 internal const string _stpCategoryHelp = "SmartThreadPool performance counters";
103 internal const string _stpCategoryName = "SmartThreadPool";
104
105 // Methods
106 static STPPerformanceCounters()
107 {
108 _instance = new STPPerformanceCounters();
109 }
110
111 private STPPerformanceCounters()
112 {
113 STPPerformanceCounter[] stpPerformanceCounters = new STPPerformanceCounter[]
114 {
115 new STPPerformanceCounter("Active threads", "The current number of available in the thread pool.", PerformanceCounterType.NumberOfItems32),
116 new STPPerformanceCounter("In use threads", "The current number of threads that execute a work item.", PerformanceCounterType.NumberOfItems32),
117 new STPPerformanceCounter("Overhead threads", "The current number of threads that are active, but are not in use.", PerformanceCounterType.NumberOfItems32),
118 new STPPerformanceCounter("% overhead threads", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawFraction),
119 new STPPerformanceCounter("% overhead threads base", "The current number of threads that are active, but are not in use in percents.", PerformanceCounterType.RawBase),
120
121 new STPPerformanceCounter("Work Items", "The number of work items in the Smart Thread Pool. Both queued and processed.", PerformanceCounterType.NumberOfItems32),
122 new STPPerformanceCounter("Work Items in queue", "The current number of work items in the queue", PerformanceCounterType.NumberOfItems32),
123 new STPPerformanceCounter("Work Items processed", "The number of work items already processed", PerformanceCounterType.NumberOfItems32),
124
125 new STPPerformanceCounter("Work Items queued/sec", "The number of work items queued per second", PerformanceCounterType.RateOfCountsPerSecond32),
126 new STPPerformanceCounter("Work Items processed/sec", "The number of work items processed per second", PerformanceCounterType.RateOfCountsPerSecond32),
127
128 new STPPerformanceCounter("Avg. Work Item wait time/sec", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageCount64),
129 new STPPerformanceCounter("Avg. Work Item wait time base", "The average time a work item supends in the queue waiting for its turn to execute.", PerformanceCounterType.AverageBase),
130
131 new STPPerformanceCounter("Avg. Work Item process time/sec", "The average time it takes to process a work item.", PerformanceCounterType.AverageCount64),
132 new STPPerformanceCounter("Avg. Work Item process time base", "The average time it takes to process a work item.", PerformanceCounterType.AverageBase),
133
134 new STPPerformanceCounter("Work Items Groups", "The current number of work item groups associated with the Smart Thread Pool.", PerformanceCounterType.NumberOfItems32),
135 };
136
137 _stpPerformanceCounters = stpPerformanceCounters;
138 SetupCategory();
139 }
140
141 private void SetupCategory()
142 {
143 if (!PerformanceCounterCategory.Exists(_stpCategoryName))
144 {
145 CounterCreationDataCollection counters = new CounterCreationDataCollection();
146
147 for (int i = 0; i < _stpPerformanceCounters.Length; i++)
148 {
149 _stpPerformanceCounters[i].AddCounterToCollection(counters);
150 }
151
152 PerformanceCounterCategory.Create(
153 _stpCategoryName,
154 _stpCategoryHelp,
155 PerformanceCounterCategoryType.MultiInstance,
156 counters);
157
158 }
159 }
160
161 // Properties
162 public static STPPerformanceCounters Instance
163 {
164 get
165 {
166 return _instance;
167 }
168 }
169 }
170
171 internal class STPInstancePerformanceCounter : IDisposable
172 {
173 // Fields
174 private bool _isDisposed;
175 private PerformanceCounter _pcs;
176
177 // Methods
178 protected STPInstancePerformanceCounter()
179 {
180 _isDisposed = false;
181 }
182
183 public STPInstancePerformanceCounter(
184 string instance,
185 STPPerformanceCounterType spcType) : this()
186 {
187 STPPerformanceCounters counters = STPPerformanceCounters.Instance;
188 _pcs = new PerformanceCounter(
189 STPPerformanceCounters._stpCategoryName,
190 counters._stpPerformanceCounters[(int) spcType].Name,
191 instance,
192 false);
193 _pcs.RawValue = _pcs.RawValue;
194 }
195
196
197 public void Close()
198 {
199 if (_pcs != null)
200 {
201 _pcs.RemoveInstance();
202 _pcs.Close();
203 _pcs = null;
204 }
205 }
206
207 public void Dispose()
208 {
209 Dispose(true);
210 }
211
212 public virtual void Dispose(bool disposing)
213 {
214 if (!_isDisposed)
215 {
216 if (disposing)
217 {
218 Close();
219 }
220 }
221 _isDisposed = true;
222 }
223
224 public virtual void Increment()
225 {
226 _pcs.Increment();
227 }
228
229 public virtual void IncrementBy(long val)
230 {
231 _pcs.IncrementBy(val);
232 }
233
234 public virtual void Set(long val)
235 {
236 _pcs.RawValue = val;
237 }
238 }
239
240 internal class STPInstanceNullPerformanceCounter : STPInstancePerformanceCounter
241 {
242 // Methods
243 public override void Increment() {}
244 public override void IncrementBy(long value) {}
245 public override void Set(long val) {}
246 }
247
248
249
250 internal class STPInstancePerformanceCounters : ISTPInstancePerformanceCounters
251 {
252 private bool _isDisposed;
253 // Fields
254 private STPInstancePerformanceCounter[] _pcs;
255 private static readonly STPInstancePerformanceCounter _stpInstanceNullPerformanceCounter;
256
257 // Methods
258 static STPInstancePerformanceCounters()
259 {
260 _stpInstanceNullPerformanceCounter = new STPInstanceNullPerformanceCounter();
261 }
262
263 public STPInstancePerformanceCounters(string instance)
264 {
265 _isDisposed = false;
266 _pcs = new STPInstancePerformanceCounter[(int)STPPerformanceCounterType.LastCounter];
267
268 // Call the STPPerformanceCounters.Instance so the static constructor will
269 // intialize the STPPerformanceCounters singleton.
270 STPPerformanceCounters.Instance.GetHashCode();
271
272 for (int i = 0; i < _pcs.Length; i++)
273 {
274 if (instance != null)
275 {
276 _pcs[i] = new STPInstancePerformanceCounter(
277 instance,
278 (STPPerformanceCounterType) i);
279 }
280 else
281 {
282 _pcs[i] = _stpInstanceNullPerformanceCounter;
283 }
284 }
285 }
286
287
288 public void Close()
289 {
290 if (null != _pcs)
291 {
292 for (int i = 0; i < _pcs.Length; i++)
293 {
294 if (null != _pcs[i])
295 {
296 _pcs[i].Dispose();
297 }
298 }
299 _pcs = null;
300 }
301 }
302
303 public void Dispose()
304 {
305 Dispose(true);
306 }
307
308 public virtual void Dispose(bool disposing)
309 {
310 if (!_isDisposed)
311 {
312 if (disposing)
313 {
314 Close();
315 }
316 }
317 _isDisposed = true;
318 }
319
320 private STPInstancePerformanceCounter GetCounter(STPPerformanceCounterType spcType)
321 {
322 return _pcs[(int) spcType];
323 }
324
325 public void SampleThreads(long activeThreads, long inUseThreads)
326 {
327 GetCounter(STPPerformanceCounterType.ActiveThreads).Set(activeThreads);
328 GetCounter(STPPerformanceCounterType.InUseThreads).Set(inUseThreads);
329 GetCounter(STPPerformanceCounterType.OverheadThreads).Set(activeThreads-inUseThreads);
330
331 GetCounter(STPPerformanceCounterType.OverheadThreadsPercentBase).Set(activeThreads-inUseThreads);
332 GetCounter(STPPerformanceCounterType.OverheadThreadsPercent).Set(inUseThreads);
333 }
334
335 public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
336 {
337 GetCounter(STPPerformanceCounterType.WorkItems).Set(workItemsQueued+workItemsProcessed);
338 GetCounter(STPPerformanceCounterType.WorkItemsInQueue).Set(workItemsQueued);
339 GetCounter(STPPerformanceCounterType.WorkItemsProcessed).Set(workItemsProcessed);
340
341 GetCounter(STPPerformanceCounterType.WorkItemsQueuedPerSecond).Set(workItemsQueued);
342 GetCounter(STPPerformanceCounterType.WorkItemsProcessedPerSecond).Set(workItemsProcessed);
343 }
344
345 public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
346 {
347 GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTime).IncrementBy((long)workItemWaitTime.TotalMilliseconds);
348 GetCounter(STPPerformanceCounterType.AvgWorkItemWaitTimeBase).Increment();
349 }
350
351 public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
352 {
353 GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTime).IncrementBy((long)workItemProcessTime.TotalMilliseconds);
354 GetCounter(STPPerformanceCounterType.AvgWorkItemProcessTimeBase).Increment();
355 }
356 }
357#endif
358
359 internal class NullSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
360 {
361 private static readonly NullSTPInstancePerformanceCounters _instance = new NullSTPInstancePerformanceCounters();
362
363 public static NullSTPInstancePerformanceCounters Instance
364 {
365 get { return _instance; }
366 }
367
368 public void Close() {}
369 public void Dispose() {}
370
371 public void SampleThreads(long activeThreads, long inUseThreads) {}
372 public void SampleWorkItems(long workItemsQueued, long workItemsProcessed) {}
373 public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime) {}
374 public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime) {}
375 public long InUseThreads
376 {
377 get { return 0; }
378 }
379
380 public long ActiveThreads
381 {
382 get { return 0; }
383 }
384
385 public long WorkItemsQueued
386 {
387 get { return 0; }
388 }
389
390 public long WorkItemsProcessed
391 {
392 get { return 0; }
393 }
394 }
395
396 internal class LocalSTPInstancePerformanceCounters : ISTPInstancePerformanceCounters, ISTPPerformanceCountersReader
397 {
398 public void Close() { }
399 public void Dispose() { }
400
401 private long _activeThreads;
402 private long _inUseThreads;
403 private long _workItemsQueued;
404 private long _workItemsProcessed;
405
406 public long InUseThreads
407 {
408 get { return _inUseThreads; }
409 }
410
411 public long ActiveThreads
412 {
413 get { return _activeThreads; }
414 }
415
416 public long WorkItemsQueued
417 {
418 get { return _workItemsQueued; }
419 }
420
421 public long WorkItemsProcessed
422 {
423 get { return _workItemsProcessed; }
424 }
425
426 public void SampleThreads(long activeThreads, long inUseThreads)
427 {
428 _activeThreads = activeThreads;
429 _inUseThreads = inUseThreads;
430 }
431
432 public void SampleWorkItems(long workItemsQueued, long workItemsProcessed)
433 {
434 _workItemsQueued = workItemsQueued;
435 _workItemsProcessed = workItemsProcessed;
436 }
437
438 public void SampleWorkItemsWaitTime(TimeSpan workItemWaitTime)
439 {
440 // Not supported
441 }
442
443 public void SampleWorkItemsProcessTime(TimeSpan workItemProcessTime)
444 {
445 // Not supported
446 }
447 }
448}
diff --git a/ThirdParty/SmartThreadPool/STPStartInfo.cs b/ThirdParty/SmartThreadPool/STPStartInfo.cs
new file mode 100644
index 0000000..8ea547c
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/STPStartInfo.cs
@@ -0,0 +1,212 @@
1using System;
2using System.Threading;
3
4namespace Amib.Threading
5{
6 /// <summary>
7 /// Summary description for STPStartInfo.
8 /// </summary>
9 public class STPStartInfo : WIGStartInfo
10 {
11 private int _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
12 private int _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
13 private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
14#if !(WINDOWS_PHONE)
15 private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority;
16#endif
17 private string _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
18 private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground;
19 private bool _enableLocalPerformanceCounters;
20 private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName;
21 private int? _maxStackSize = SmartThreadPool.DefaultMaxStackSize;
22
23 public STPStartInfo()
24 {
25 _performanceCounterInstanceName = SmartThreadPool.DefaultPerformanceCounterInstanceName;
26#if !(WINDOWS_PHONE)
27 _threadPriority = SmartThreadPool.DefaultThreadPriority;
28#endif
29 _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
30 _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
31 _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
32 }
33
34 public STPStartInfo(STPStartInfo stpStartInfo)
35 : base(stpStartInfo)
36 {
37 _idleTimeout = stpStartInfo.IdleTimeout;
38 _minWorkerThreads = stpStartInfo.MinWorkerThreads;
39 _maxWorkerThreads = stpStartInfo.MaxWorkerThreads;
40#if !(WINDOWS_PHONE)
41 _threadPriority = stpStartInfo.ThreadPriority;
42#endif
43 _performanceCounterInstanceName = stpStartInfo.PerformanceCounterInstanceName;
44 _enableLocalPerformanceCounters = stpStartInfo._enableLocalPerformanceCounters;
45 _threadPoolName = stpStartInfo._threadPoolName;
46 _areThreadsBackground = stpStartInfo.AreThreadsBackground;
47#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
48 _apartmentState = stpStartInfo._apartmentState;
49#endif
50 }
51
52 /// <summary>
53 /// Get/Set the idle timeout in milliseconds.
54 /// If a thread is idle (starved) longer than IdleTimeout then it may quit.
55 /// </summary>
56 public virtual int IdleTimeout
57 {
58 get { return _idleTimeout; }
59 set
60 {
61 ThrowIfReadOnly();
62 _idleTimeout = value;
63 }
64 }
65
66
67 /// <summary>
68 /// Get/Set the lower limit of threads in the pool.
69 /// </summary>
70 public virtual int MinWorkerThreads
71 {
72 get { return _minWorkerThreads; }
73 set
74 {
75 ThrowIfReadOnly();
76 _minWorkerThreads = value;
77 }
78 }
79
80
81 /// <summary>
82 /// Get/Set the upper limit of threads in the pool.
83 /// </summary>
84 public virtual int MaxWorkerThreads
85 {
86 get { return _maxWorkerThreads; }
87 set
88 {
89 ThrowIfReadOnly();
90 _maxWorkerThreads = value;
91 }
92 }
93
94#if !(WINDOWS_PHONE)
95 /// <summary>
96 /// Get/Set the scheduling priority of the threads in the pool.
97 /// The Os handles the scheduling.
98 /// </summary>
99 public virtual ThreadPriority ThreadPriority
100 {
101 get { return _threadPriority; }
102 set
103 {
104 ThrowIfReadOnly();
105 _threadPriority = value;
106 }
107 }
108#endif
109 /// <summary>
110 /// Get/Set the thread pool name. Threads will get names depending on this.
111 /// </summary>
112 public virtual string ThreadPoolName {
113 get { return _threadPoolName; }
114 set
115 {
116 ThrowIfReadOnly ();
117 _threadPoolName = value;
118 }
119 }
120
121 /// <summary>
122 /// Get/Set the performance counter instance name of this SmartThreadPool
123 /// The default is null which indicate not to use performance counters at all.
124 /// </summary>
125 public virtual string PerformanceCounterInstanceName
126 {
127 get { return _performanceCounterInstanceName; }
128 set
129 {
130 ThrowIfReadOnly();
131 _performanceCounterInstanceName = value;
132 }
133 }
134
135 /// <summary>
136 /// Enable/Disable the local performance counter.
137 /// This enables the user to get some performance information about the SmartThreadPool
138 /// without using Windows performance counters. (Useful on WindowsCE, Silverlight, etc.)
139 /// The default is false.
140 /// </summary>
141 public virtual bool EnableLocalPerformanceCounters
142 {
143 get { return _enableLocalPerformanceCounters; }
144 set
145 {
146 ThrowIfReadOnly();
147 _enableLocalPerformanceCounters = value;
148 }
149 }
150
151 /// <summary>
152 /// Get/Set backgroundness of thread in thread pool.
153 /// </summary>
154 public virtual bool AreThreadsBackground
155 {
156 get { return _areThreadsBackground; }
157 set
158 {
159 ThrowIfReadOnly ();
160 _areThreadsBackground = value;
161 }
162 }
163
164 /// <summary>
165 /// Get a readonly version of this STPStartInfo.
166 /// </summary>
167 /// <returns>Returns a readonly reference to this STPStartInfo</returns>
168 public new STPStartInfo AsReadOnly()
169 {
170 return new STPStartInfo(this) { _readOnly = true };
171 }
172
173#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
174
175 private ApartmentState _apartmentState = SmartThreadPool.DefaultApartmentState;
176
177 /// <summary>
178 /// Get/Set the apartment state of threads in the thread pool
179 /// </summary>
180 public ApartmentState ApartmentState
181 {
182 get { return _apartmentState; }
183 set
184 {
185 ThrowIfReadOnly();
186 _apartmentState = value;
187 }
188 }
189
190#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
191
192 /// <summary>
193 /// Get/Set the max stack size of threads in the thread pool
194 /// </summary>
195 public int? MaxStackSize
196 {
197 get { return _maxStackSize; }
198 set
199 {
200 ThrowIfReadOnly();
201 if (value.HasValue && value.Value < 0)
202 {
203 throw new ArgumentOutOfRangeException("value", "Value must be greater than 0.");
204 }
205 _maxStackSize = value;
206 }
207 }
208#endif
209
210#endif
211 }
212}
diff --git a/ThirdParty/SmartThreadPool/SmartThreadPool.ThreadEntry.cs b/ThirdParty/SmartThreadPool/SmartThreadPool.ThreadEntry.cs
new file mode 100644
index 0000000..4713332
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/SmartThreadPool.ThreadEntry.cs
@@ -0,0 +1,60 @@
1
2using System;
3using Amib.Threading.Internal;
4
5namespace Amib.Threading
6{
7 public partial class SmartThreadPool
8 {
9 #region ThreadEntry class
10
11 internal class ThreadEntry
12 {
13 /// <summary>
14 /// The thread creation time
15 /// The value is stored as UTC value.
16 /// </summary>
17 private readonly DateTime _creationTime;
18
19 /// <summary>
20 /// The last time this thread has been running
21 /// It is updated by IAmAlive() method
22 /// The value is stored as UTC value.
23 /// </summary>
24 private DateTime _lastAliveTime;
25
26 /// <summary>
27 /// A reference from each thread in the thread pool to its SmartThreadPool
28 /// object container.
29 /// With this variable a thread can know whatever it belongs to a
30 /// SmartThreadPool.
31 /// </summary>
32 private readonly SmartThreadPool _associatedSmartThreadPool;
33
34 /// <summary>
35 /// A reference to the current work item a thread from the thread pool
36 /// is executing.
37 /// </summary>
38 public WorkItem CurrentWorkItem { get; set; }
39
40 public ThreadEntry(SmartThreadPool stp)
41 {
42 _associatedSmartThreadPool = stp;
43 _creationTime = DateTime.UtcNow;
44 _lastAliveTime = DateTime.MinValue;
45 }
46
47 public SmartThreadPool AssociatedSmartThreadPool
48 {
49 get { return _associatedSmartThreadPool; }
50 }
51
52 public void IAmAlive()
53 {
54 _lastAliveTime = DateTime.UtcNow;
55 }
56 }
57
58 #endregion
59 }
60} \ No newline at end of file
diff --git a/ThirdParty/SmartThreadPool/SmartThreadPool.cs b/ThirdParty/SmartThreadPool/SmartThreadPool.cs
new file mode 100644
index 0000000..7cc7fbf
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/SmartThreadPool.cs
@@ -0,0 +1,1737 @@
1#region Release History
2
3// Smart Thread Pool
4// 7 Aug 2004 - Initial release
5//
6// 14 Sep 2004 - Bug fixes
7//
8// 15 Oct 2004 - Added new features
9// - Work items return result.
10// - Support waiting synchronization for multiple work items.
11// - Work items can be cancelled.
12// - Passage of the caller thread’s context to the thread in the pool.
13// - Minimal usage of WIN32 handles.
14// - Minor bug fixes.
15//
16// 26 Dec 2004 - Changes:
17// - Removed static constructors.
18// - Added finalizers.
19// - Changed Exceptions so they are serializable.
20// - Fixed the bug in one of the SmartThreadPool constructors.
21// - Changed the SmartThreadPool.WaitAll() so it will support any number of waiters.
22// The SmartThreadPool.WaitAny() is still limited by the .NET Framework.
23// - Added PostExecute with options on which cases to call it.
24// - Added option to dispose of the state objects.
25// - Added a WaitForIdle() method that waits until the work items queue is empty.
26// - Added an STPStartInfo class for the initialization of the thread pool.
27// - Changed exception handling so if a work item throws an exception it
28// is rethrown at GetResult(), rather then firing an UnhandledException event.
29// Note that PostExecute exception are always ignored.
30//
31// 25 Mar 2005 - Changes:
32// - Fixed lost of work items bug
33//
34// 3 Jul 2005: Changes.
35// - Fixed bug where Enqueue() throws an exception because PopWaiter() returned null, hardly reconstructed.
36//
37// 16 Aug 2005: Changes.
38// - Fixed bug where the InUseThreads becomes negative when canceling work items.
39//
40// 31 Jan 2006 - Changes:
41// - Added work items priority
42// - Removed support of chained delegates in callbacks and post executes (nobody really use this)
43// - Added work items groups
44// - Added work items groups idle event
45// - Changed SmartThreadPool.WaitAll() behavior so when it gets empty array
46// it returns true rather then throwing an exception.
47// - Added option to start the STP and the WIG as suspended
48// - Exception behavior changed, the real exception is returned by an
49// inner exception
50// - Added option to keep the Http context of the caller thread. (Thanks to Steven T.)
51// - Added performance counters
52// - Added priority to the threads in the pool
53//
54// 13 Feb 2006 - Changes:
55// - Added a call to the dispose of the Performance Counter so
56// their won't be a Performance Counter leak.
57// - Added exception catch in case the Performance Counters cannot
58// be created.
59//
60// 17 May 2008 - Changes:
61// - Changed the dispose behavior and removed the Finalizers.
62// - Enabled the change of the MaxThreads and MinThreads at run time.
63// - Enabled the change of the Concurrency of a IWorkItemsGroup at run
64// time If the IWorkItemsGroup is a SmartThreadPool then the Concurrency
65// refers to the MaxThreads.
66// - Improved the cancel behavior.
67// - Added events for thread creation and termination.
68// - Fixed the HttpContext context capture.
69// - Changed internal collections so they use generic collections
70// - Added IsIdle flag to the SmartThreadPool and IWorkItemsGroup
71// - Added support for WinCE
72// - Added support for Action<T> and Func<T>
73//
74// 07 April 2009 - Changes:
75// - Added support for Silverlight and Mono
76// - Added Join, Choice, and Pipe to SmartThreadPool.
77// - Added local performance counters (for Mono, Silverlight, and WindowsCE)
78// - Changed duration measures from DateTime.Now to Stopwatch.
79// - Queues changed from System.Collections.Queue to System.Collections.Generic.LinkedList<T>.
80//
81// 21 December 2009 - Changes:
82// - Added work item timeout (passive)
83//
84// 20 August 2012 - Changes:
85// - Added set name to threads
86// - Fixed the WorkItemsQueue.Dequeue.
87// Replaced while (!Monitor.TryEnter(this)); with lock(this) { ... }
88// - Fixed SmartThreadPool.Pipe
89// - Added IsBackground option to threads
90// - Added ApartmentState to threads
91// - Fixed thread creation when queuing many work items at the same time.
92//
93// 24 August 2012 - Changes:
94// - Enabled cancel abort after cancel. See: http://smartthreadpool.codeplex.com/discussions/345937 by alecswan
95// - Added option to set MaxStackSize of threads
96
97#endregion
98
99using System;
100using System.Security;
101using System.Threading;
102using System.Collections;
103using System.Collections.Generic;
104using System.Diagnostics;
105using System.Runtime.CompilerServices;
106
107using Amib.Threading.Internal;
108
109namespace Amib.Threading
110{
111 #region SmartThreadPool class
112 /// <summary>
113 /// Smart thread pool class.
114 /// </summary>
115 public partial class SmartThreadPool : WorkItemsGroupBase, IDisposable
116 {
117 #region Public Default Constants
118
119 /// <summary>
120 /// Default minimum number of threads the thread pool contains. (0)
121 /// </summary>
122 public const int DefaultMinWorkerThreads = 0;
123
124 /// <summary>
125 /// Default maximum number of threads the thread pool contains. (25)
126 /// </summary>
127 public const int DefaultMaxWorkerThreads = 25;
128
129 /// <summary>
130 /// Default idle timeout in milliseconds. (One minute)
131 /// </summary>
132 public const int DefaultIdleTimeout = 60*1000; // One minute
133
134 /// <summary>
135 /// Indicate to copy the security context of the caller and then use it in the call. (false)
136 /// </summary>
137 public const bool DefaultUseCallerCallContext = false;
138
139 /// <summary>
140 /// Indicate to copy the HTTP context of the caller and then use it in the call. (false)
141 /// </summary>
142 public const bool DefaultUseCallerHttpContext = false;
143
144 /// <summary>
145 /// Indicate to dispose of the state objects if they support the IDispose interface. (false)
146 /// </summary>
147 public const bool DefaultDisposeOfStateObjects = false;
148
149 /// <summary>
150 /// The default option to run the post execute (CallToPostExecute.Always)
151 /// </summary>
152 public const CallToPostExecute DefaultCallToPostExecute = CallToPostExecute.Always;
153
154 /// <summary>
155 /// The default post execute method to run. (None)
156 /// When null it means not to call it.
157 /// </summary>
158 public static readonly PostExecuteWorkItemCallback DefaultPostExecuteWorkItemCallback;
159
160 /// <summary>
161 /// The default work item priority (WorkItemPriority.Normal)
162 /// </summary>
163 public const WorkItemPriority DefaultWorkItemPriority = WorkItemPriority.Normal;
164
165 /// <summary>
166 /// The default is to work on work items as soon as they arrive
167 /// and not to wait for the start. (false)
168 /// </summary>
169 public const bool DefaultStartSuspended = false;
170
171 /// <summary>
172 /// The default name to use for the performance counters instance. (null)
173 /// </summary>
174 public static readonly string DefaultPerformanceCounterInstanceName;
175
176#if !(WINDOWS_PHONE)
177
178 /// <summary>
179 /// The default thread priority (ThreadPriority.Normal)
180 /// </summary>
181 public const ThreadPriority DefaultThreadPriority = ThreadPriority.Normal;
182#endif
183 /// <summary>
184 /// The default thread pool name. (SmartThreadPool)
185 /// </summary>
186 public const string DefaultThreadPoolName = "SmartThreadPool";
187
188 /// <summary>
189 /// The default Max Stack Size. (SmartThreadPool)
190 /// </summary>
191 public static readonly int? DefaultMaxStackSize = null;
192
193 /// <summary>
194 /// The default fill state with params. (false)
195 /// It is relevant only to QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt;
196 /// </summary>
197 public const bool DefaultFillStateWithArgs = false;
198
199 /// <summary>
200 /// The default thread backgroundness. (true)
201 /// </summary>
202 public const bool DefaultAreThreadsBackground = true;
203
204#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
205 /// <summary>
206 /// The default apartment state of a thread in the thread pool.
207 /// The default is ApartmentState.Unknown which means the STP will not
208 /// set the apartment of the thread. It will use the .NET default.
209 /// </summary>
210 public const ApartmentState DefaultApartmentState = ApartmentState.Unknown;
211#endif
212
213 #endregion
214
215 #region Member Variables
216
217 /// <summary>
218 /// Dictionary of all the threads in the thread pool.
219 /// </summary>
220 private readonly SynchronizedDictionary<Thread, ThreadEntry> _workerThreads = new SynchronizedDictionary<Thread, ThreadEntry>();
221
222 /// <summary>
223 /// Queue of work items.
224 /// </summary>
225 private readonly WorkItemsQueue _workItemsQueue = new WorkItemsQueue();
226
227 /// <summary>
228 /// Count the work items handled.
229 /// Used by the performance counter.
230 /// </summary>
231 private int _workItemsProcessed;
232
233 /// <summary>
234 /// Number of threads that currently work (not idle).
235 /// </summary>
236 private int _inUseWorkerThreads;
237
238 /// <summary>
239 /// Stores a copy of the original STPStartInfo.
240 /// It is used to change the MinThread and MaxThreads
241 /// </summary>
242 private STPStartInfo _stpStartInfo;
243
244 /// <summary>
245 /// Total number of work items that are stored in the work items queue
246 /// plus the work items that the threads in the pool are working on.
247 /// </summary>
248 private int _currentWorkItemsCount;
249
250 /// <summary>
251 /// Signaled when the thread pool is idle, i.e. no thread is busy
252 /// and the work items queue is empty
253 /// </summary>
254 //private ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true);
255 private ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true);
256
257 /// <summary>
258 /// An event to signal all the threads to quit immediately.
259 /// </summary>
260 //private ManualResetEvent _shuttingDownEvent = new ManualResetEvent(false);
261 private ManualResetEvent _shuttingDownEvent = EventWaitHandleFactory.CreateManualResetEvent(false);
262
263 /// <summary>
264 /// A flag to indicate if the Smart Thread Pool is now suspended.
265 /// </summary>
266 private bool _isSuspended;
267
268 /// <summary>
269 /// A flag to indicate the threads to quit.
270 /// </summary>
271 private bool _shutdown;
272
273 /// <summary>
274 /// Counts the threads created in the pool.
275 /// It is used to name the threads.
276 /// </summary>
277 private int _threadCounter;
278
279 /// <summary>
280 /// Indicate that the SmartThreadPool has been disposed
281 /// </summary>
282 private bool _isDisposed;
283
284 /// <summary>
285 /// Holds all the WorkItemsGroup instaces that have at least one
286 /// work item int the SmartThreadPool
287 /// This variable is used in case of Shutdown
288 /// </summary>
289 private readonly SynchronizedDictionary<IWorkItemsGroup, IWorkItemsGroup> _workItemsGroups = new SynchronizedDictionary<IWorkItemsGroup, IWorkItemsGroup>();
290
291 /// <summary>
292 /// A common object for all the work items int the STP
293 /// so we can mark them to cancel in O(1)
294 /// </summary>
295 private CanceledWorkItemsGroup _canceledSmartThreadPool = new CanceledWorkItemsGroup();
296
297 /// <summary>
298 /// Windows STP performance counters
299 /// </summary>
300 private ISTPInstancePerformanceCounters _windowsPCs = NullSTPInstancePerformanceCounters.Instance;
301
302 /// <summary>
303 /// Local STP performance counters
304 /// </summary>
305 private ISTPInstancePerformanceCounters _localPCs = NullSTPInstancePerformanceCounters.Instance;
306
307
308#if (WINDOWS_PHONE)
309 private static readonly Dictionary<int, ThreadEntry> _threadEntries = new Dictionary<int, ThreadEntry>();
310#elif (_WINDOWS_CE)
311 private static LocalDataStoreSlot _threadEntrySlot = Thread.AllocateDataSlot();
312#else
313 [ThreadStatic]
314 private static ThreadEntry _threadEntry;
315
316#endif
317
318 /// <summary>
319 /// An event to call after a thread is created, but before
320 /// it's first use.
321 /// </summary>
322 private event ThreadInitializationHandler _onThreadInitialization;
323
324 /// <summary>
325 /// An event to call when a thread is about to exit, after
326 /// it is no longer belong to the pool.
327 /// </summary>
328 private event ThreadTerminationHandler _onThreadTermination;
329
330 #endregion
331
332 #region Per thread properties
333
334 /// <summary>
335 /// A reference to the current work item a thread from the thread pool
336 /// is executing.
337 /// </summary>
338 internal static ThreadEntry CurrentThreadEntry
339 {
340#if (WINDOWS_PHONE)
341 get
342 {
343 lock(_threadEntries)
344 {
345 ThreadEntry threadEntry;
346 if (_threadEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out threadEntry))
347 {
348 return threadEntry;
349 }
350 }
351 return null;
352 }
353 set
354 {
355 lock(_threadEntries)
356 {
357 _threadEntries[Thread.CurrentThread.ManagedThreadId] = value;
358 }
359 }
360#elif (_WINDOWS_CE)
361 get
362 {
363 //Thread.CurrentThread.ManagedThreadId
364 return Thread.GetData(_threadEntrySlot) as ThreadEntry;
365 }
366 set
367 {
368 Thread.SetData(_threadEntrySlot, value);
369 }
370#else
371 get
372 {
373 return _threadEntry;
374 }
375 set
376 {
377 _threadEntry = value;
378 }
379#endif
380 }
381 #endregion
382
383 #region Construction and Finalization
384
385 /// <summary>
386 /// Constructor
387 /// </summary>
388 public SmartThreadPool()
389 {
390 _stpStartInfo = new STPStartInfo();
391 Initialize();
392 }
393
394 /// <summary>
395 /// Constructor
396 /// </summary>
397 /// <param name="idleTimeout">Idle timeout in milliseconds</param>
398 public SmartThreadPool(int idleTimeout)
399 {
400 _stpStartInfo = new STPStartInfo
401 {
402 IdleTimeout = idleTimeout,
403 };
404 Initialize();
405 }
406
407 /// <summary>
408 /// Constructor
409 /// </summary>
410 /// <param name="idleTimeout">Idle timeout in milliseconds</param>
411 /// <param name="maxWorkerThreads">Upper limit of threads in the pool</param>
412 public SmartThreadPool(
413 int idleTimeout,
414 int maxWorkerThreads)
415 {
416 _stpStartInfo = new STPStartInfo
417 {
418 IdleTimeout = idleTimeout,
419 MaxWorkerThreads = maxWorkerThreads,
420 };
421 Initialize();
422 }
423
424 /// <summary>
425 /// Constructor
426 /// </summary>
427 /// <param name="idleTimeout">Idle timeout in milliseconds</param>
428 /// <param name="maxWorkerThreads">Upper limit of threads in the pool</param>
429 /// <param name="minWorkerThreads">Lower limit of threads in the pool</param>
430 public SmartThreadPool(
431 int idleTimeout,
432 int maxWorkerThreads,
433 int minWorkerThreads)
434 {
435 _stpStartInfo = new STPStartInfo
436 {
437 IdleTimeout = idleTimeout,
438 MaxWorkerThreads = maxWorkerThreads,
439 MinWorkerThreads = minWorkerThreads,
440 };
441 Initialize();
442 }
443
444 /// <summary>
445 /// Constructor
446 /// </summary>
447 /// <param name="stpStartInfo">A SmartThreadPool configuration that overrides the default behavior</param>
448 public SmartThreadPool(STPStartInfo stpStartInfo)
449 {
450 _stpStartInfo = new STPStartInfo(stpStartInfo);
451 Initialize();
452 }
453
454 private void Initialize()
455 {
456 Name = _stpStartInfo.ThreadPoolName;
457 ValidateSTPStartInfo();
458
459 // _stpStartInfoRW stores a read/write copy of the STPStartInfo.
460 // Actually only MaxWorkerThreads and MinWorkerThreads are overwritten
461
462 _isSuspended = _stpStartInfo.StartSuspended;
463
464#if (_WINDOWS_CE) || (_SILVERLIGHT) || (_MONO) || (WINDOWS_PHONE)
465 if (null != _stpStartInfo.PerformanceCounterInstanceName)
466 {
467 throw new NotSupportedException("Performance counters are not implemented for Compact Framework/Silverlight/Mono, instead use StpStartInfo.EnableLocalPerformanceCounters");
468 }
469#else
470 if (null != _stpStartInfo.PerformanceCounterInstanceName)
471 {
472 try
473 {
474 _windowsPCs = new STPInstancePerformanceCounters(_stpStartInfo.PerformanceCounterInstanceName);
475 }
476 catch (Exception e)
477 {
478 Debug.WriteLine("Unable to create Performance Counters: " + e);
479 _windowsPCs = NullSTPInstancePerformanceCounters.Instance;
480 }
481 }
482#endif
483
484 if (_stpStartInfo.EnableLocalPerformanceCounters)
485 {
486 _localPCs = new LocalSTPInstancePerformanceCounters();
487 }
488
489 // If the STP is not started suspended then start the threads.
490 if (!_isSuspended)
491 {
492 StartOptimalNumberOfThreads();
493 }
494 }
495
496 private void StartOptimalNumberOfThreads()
497 {
498 int threadsCount = Math.Max(_workItemsQueue.Count, _stpStartInfo.MinWorkerThreads);
499 threadsCount = Math.Min(threadsCount, _stpStartInfo.MaxWorkerThreads);
500 threadsCount -= _workerThreads.Count;
501 if (threadsCount > 0)
502 {
503 StartThreads(threadsCount);
504 }
505 }
506
507 private void ValidateSTPStartInfo()
508 {
509 if (_stpStartInfo.MinWorkerThreads < 0)
510 {
511 throw new ArgumentOutOfRangeException(
512 "MinWorkerThreads", "MinWorkerThreads cannot be negative");
513 }
514
515 if (_stpStartInfo.MaxWorkerThreads <= 0)
516 {
517 throw new ArgumentOutOfRangeException(
518 "MaxWorkerThreads", "MaxWorkerThreads must be greater than zero");
519 }
520
521 if (_stpStartInfo.MinWorkerThreads > _stpStartInfo.MaxWorkerThreads)
522 {
523 throw new ArgumentOutOfRangeException(
524 "MinWorkerThreads, maxWorkerThreads",
525 "MaxWorkerThreads must be greater or equal to MinWorkerThreads");
526 }
527 }
528
529 private static void ValidateCallback(Delegate callback)
530 {
531 if(callback.GetInvocationList().Length > 1)
532 {
533 throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
534 }
535 }
536
537 #endregion
538
539 #region Thread Processing
540
541 /// <summary>
542 /// Waits on the queue for a work item, shutdown, or timeout.
543 /// </summary>
544 /// <returns>
545 /// Returns the WaitingCallback or null in case of timeout or shutdown.
546 /// </returns>
547 private WorkItem Dequeue()
548 {
549 WorkItem workItem =
550 _workItemsQueue.DequeueWorkItem(_stpStartInfo.IdleTimeout, _shuttingDownEvent);
551
552 return workItem;
553 }
554
555 /// <summary>
556 /// Put a new work item in the queue
557 /// </summary>
558 /// <param name="workItem">A work item to queue</param>
559 internal override void Enqueue(WorkItem workItem)
560 {
561 // Make sure the workItem is not null
562 Debug.Assert(null != workItem);
563
564 IncrementWorkItemsCount();
565
566 workItem.CanceledSmartThreadPool = _canceledSmartThreadPool;
567 _workItemsQueue.EnqueueWorkItem(workItem);
568 workItem.WorkItemIsQueued();
569
570 // If all the threads are busy then try to create a new one
571 if (_currentWorkItemsCount > _workerThreads.Count)
572 {
573 StartThreads(1);
574 }
575 }
576
577 private void IncrementWorkItemsCount()
578 {
579 _windowsPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
580 _localPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
581
582 int count = Interlocked.Increment(ref _currentWorkItemsCount);
583 //Trace.WriteLine("WorkItemsCount = " + _currentWorkItemsCount.ToString());
584 if (count == 1)
585 {
586 IsIdle = false;
587 _isIdleWaitHandle.Reset();
588 }
589 }
590
591 private void DecrementWorkItemsCount()
592 {
593 int count = Interlocked.Decrement(ref _currentWorkItemsCount);
594 //Trace.WriteLine("WorkItemsCount = " + _currentWorkItemsCount.ToString());
595 if (count == 0)
596 {
597 IsIdle = true;
598 _isIdleWaitHandle.Set();
599 }
600
601 Interlocked.Increment(ref _workItemsProcessed);
602
603 if (!_shutdown)
604 {
605 // The counter counts even if the work item was cancelled
606 _windowsPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
607 _localPCs.SampleWorkItems(_workItemsQueue.Count, _workItemsProcessed);
608 }
609
610 }
611
612 internal void RegisterWorkItemsGroup(IWorkItemsGroup workItemsGroup)
613 {
614 _workItemsGroups[workItemsGroup] = workItemsGroup;
615 }
616
617 internal void UnregisterWorkItemsGroup(IWorkItemsGroup workItemsGroup)
618 {
619 if (_workItemsGroups.Contains(workItemsGroup))
620 {
621 _workItemsGroups.Remove(workItemsGroup);
622 }
623 }
624
625 /// <summary>
626 /// Inform that the current thread is about to quit or quiting.
627 /// The same thread may call this method more than once.
628 /// </summary>
629 private void InformCompleted()
630 {
631 // There is no need to lock the two methods together
632 // since only the current thread removes itself
633 // and the _workerThreads is a synchronized dictionary
634 if (_workerThreads.Contains(Thread.CurrentThread))
635 {
636 _workerThreads.Remove(Thread.CurrentThread);
637 _windowsPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
638 _localPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
639 }
640 }
641
642 /// <summary>
643 /// Starts new threads
644 /// </summary>
645 /// <param name="threadsCount">The number of threads to start</param>
646 private void StartThreads(int threadsCount)
647 {
648 if (_isSuspended)
649 {
650 return;
651 }
652
653 lock(_workerThreads.SyncRoot)
654 {
655 // Don't start threads on shut down
656 if (_shutdown)
657 {
658 return;
659 }
660
661 for(int i = 0; i < threadsCount; ++i)
662 {
663 // Don't create more threads then the upper limit
664 if (_workerThreads.Count >= _stpStartInfo.MaxWorkerThreads)
665 {
666 return;
667 }
668
669 // Create a new thread
670
671#if (_SILVERLIGHT) || (WINDOWS_PHONE)
672 Thread workerThread = new Thread(ProcessQueuedItems);
673#else
674 Thread workerThread =
675 _stpStartInfo.MaxStackSize.HasValue
676 ? new Thread(ProcessQueuedItems, _stpStartInfo.MaxStackSize.Value)
677 : new Thread(ProcessQueuedItems);
678#endif
679 // Configure the new thread and start it
680 workerThread.IsBackground = _stpStartInfo.AreThreadsBackground;
681
682#if !(_SILVERLIGHT) && !(_WINDOWS_CE) && !(WINDOWS_PHONE)
683 if (_stpStartInfo.ApartmentState != ApartmentState.Unknown)
684 {
685 workerThread.SetApartmentState(_stpStartInfo.ApartmentState);
686 }
687#endif
688
689#if !(_SILVERLIGHT) && !(WINDOWS_PHONE)
690 workerThread.Priority = _stpStartInfo.ThreadPriority;
691#endif
692 workerThread.Name = string.Format("STP:{0}:{1}", Name, _threadCounter);
693 workerThread.Start();
694
695 ++_threadCounter;
696
697 // Add it to the dictionary and update its creation time.
698 _workerThreads[workerThread] = new ThreadEntry(this);
699
700 _windowsPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
701 _localPCs.SampleThreads(_workerThreads.Count, _inUseWorkerThreads);
702 }
703 }
704 }
705
706 /// <summary>
707 /// A worker thread method that processes work items from the work items queue.
708 /// </summary>
709 private void ProcessQueuedItems()
710 {
711 // Keep the entry of the dictionary as thread's variable to avoid the synchronization locks
712 // of the dictionary.
713 CurrentThreadEntry = _workerThreads[Thread.CurrentThread];
714
715 FireOnThreadInitialization();
716
717 try
718 {
719 bool bInUseWorkerThreadsWasIncremented = false;
720
721 // Process until shutdown.
722 while(!_shutdown)
723 {
724 // Update the last time this thread was seen alive.
725 // It's good for debugging.
726 CurrentThreadEntry.IAmAlive();
727
728 // The following block handles the when the MaxWorkerThreads has been
729 // incremented by the user at run-time.
730 // Double lock for quit.
731 if (_workerThreads.Count > _stpStartInfo.MaxWorkerThreads)
732 {
733 lock (_workerThreads.SyncRoot)
734 {
735 if (_workerThreads.Count > _stpStartInfo.MaxWorkerThreads)
736 {
737 // Inform that the thread is quiting and then quit.
738 // This method must be called within this lock or else
739 // more threads will quit and the thread pool will go
740 // below the lower limit.
741 InformCompleted();
742 break;
743 }
744 }
745 }
746
747 // Wait for a work item, shutdown, or timeout
748 WorkItem workItem = Dequeue();
749
750 // Update the last time this thread was seen alive.
751 // It's good for debugging.
752 CurrentThreadEntry.IAmAlive();
753
754 // On timeout or shut down.
755 if (null == workItem)
756 {
757 // Double lock for quit.
758 if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads)
759 {
760 lock(_workerThreads.SyncRoot)
761 {
762 if (_workerThreads.Count > _stpStartInfo.MinWorkerThreads)
763 {
764 // Inform that the thread is quiting and then quit.
765 // This method must be called within this lock or else
766 // more threads will quit and the thread pool will go
767 // below the lower limit.
768 InformCompleted();
769 break;
770 }
771 }
772 }
773 }
774
775 // If we didn't quit then skip to the next iteration.
776 if (null == workItem)
777 {
778 continue;
779 }
780
781 try
782 {
783 // Initialize the value to false
784 bInUseWorkerThreadsWasIncremented = false;
785
786 // Set the Current Work Item of the thread.
787 // Store the Current Work Item before the workItem.StartingWorkItem() is called,
788 // so WorkItem.Cancel can work when the work item is between InQueue and InProgress
789 // states.
790 // If the work item has been cancelled BEFORE the workItem.StartingWorkItem()
791 // (work item is in InQueue state) then workItem.StartingWorkItem() will return false.
792 // If the work item has been cancelled AFTER the workItem.StartingWorkItem() then
793 // (work item is in InProgress state) then the thread will be aborted
794 CurrentThreadEntry.CurrentWorkItem = workItem;
795
796 // Change the state of the work item to 'in progress' if possible.
797 // We do it here so if the work item has been canceled we won't
798 // increment the _inUseWorkerThreads.
799 // The cancel mechanism doesn't delete items from the queue,
800 // it marks the work item as canceled, and when the work item
801 // is dequeued, we just skip it.
802 // If the post execute of work item is set to always or to
803 // call when the work item is canceled then the StartingWorkItem()
804 // will return true, so the post execute can run.
805 if (!workItem.StartingWorkItem())
806 {
807 continue;
808 }
809
810 // Execute the callback. Make sure to accurately
811 // record how many callbacks are currently executing.
812 int inUseWorkerThreads = Interlocked.Increment(ref _inUseWorkerThreads);
813 _windowsPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
814 _localPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
815
816 // Mark that the _inUseWorkerThreads incremented, so in the finally{}
817 // statement we will decrement it correctly.
818 bInUseWorkerThreadsWasIncremented = true;
819
820 workItem.FireWorkItemStarted();
821
822 ExecuteWorkItem(workItem);
823 }
824 catch(Exception ex)
825 {
826 ex.GetHashCode();
827 // Do nothing
828 }
829 finally
830 {
831 workItem.DisposeOfState();
832
833 // Set the CurrentWorkItem to null, since we
834 // no longer run user's code.
835 CurrentThreadEntry.CurrentWorkItem = null;
836
837 // Decrement the _inUseWorkerThreads only if we had
838 // incremented it. Note the cancelled work items don't
839 // increment _inUseWorkerThreads.
840 if (bInUseWorkerThreadsWasIncremented)
841 {
842 int inUseWorkerThreads = Interlocked.Decrement(ref _inUseWorkerThreads);
843 _windowsPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
844 _localPCs.SampleThreads(_workerThreads.Count, inUseWorkerThreads);
845 }
846
847 // Notify that the work item has been completed.
848 // WorkItemsGroup may enqueue their next work item.
849 workItem.FireWorkItemCompleted();
850
851 // Decrement the number of work items here so the idle
852 // ManualResetEvent won't fluctuate.
853 DecrementWorkItemsCount();
854 }
855 }
856 }
857 catch(ThreadAbortException tae)
858 {
859 tae.GetHashCode();
860 // Handle the abort exception gracfully.
861#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
862 Thread.ResetAbort();
863#endif
864 }
865 catch(Exception e)
866 {
867 Debug.Assert(null != e);
868 }
869 finally
870 {
871 InformCompleted();
872 FireOnThreadTermination();
873 }
874 }
875
876 private void ExecuteWorkItem(WorkItem workItem)
877 {
878 _windowsPCs.SampleWorkItemsWaitTime(workItem.WaitingTime);
879 _localPCs.SampleWorkItemsWaitTime(workItem.WaitingTime);
880 try
881 {
882 workItem.Execute();
883 }
884 finally
885 {
886 _windowsPCs.SampleWorkItemsProcessTime(workItem.ProcessTime);
887 _localPCs.SampleWorkItemsProcessTime(workItem.ProcessTime);
888 }
889 }
890
891
892 #endregion
893
894 #region Public Methods
895
896 private void ValidateWaitForIdle()
897 {
898 if (null != CurrentThreadEntry && CurrentThreadEntry.AssociatedSmartThreadPool == this)
899 {
900 throw new NotSupportedException(
901 "WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
902 }
903 }
904
905 internal static void ValidateWorkItemsGroupWaitForIdle(IWorkItemsGroup workItemsGroup)
906 {
907 if (null == CurrentThreadEntry)
908 {
909 return;
910 }
911
912 WorkItem workItem = CurrentThreadEntry.CurrentWorkItem;
913 ValidateWorkItemsGroupWaitForIdleImpl(workItemsGroup, workItem);
914 if ((null != workItemsGroup) &&
915 (null != workItem) &&
916 CurrentThreadEntry.CurrentWorkItem.WasQueuedBy(workItemsGroup))
917 {
918 throw new NotSupportedException("WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
919 }
920 }
921
922 [MethodImpl(MethodImplOptions.NoInlining)]
923 private static void ValidateWorkItemsGroupWaitForIdleImpl(IWorkItemsGroup workItemsGroup, WorkItem workItem)
924 {
925 if ((null != workItemsGroup) &&
926 (null != workItem) &&
927 workItem.WasQueuedBy(workItemsGroup))
928 {
929 throw new NotSupportedException("WaitForIdle cannot be called from a thread on its SmartThreadPool, it causes a deadlock");
930 }
931 }
932
933 /// <summary>
934 /// Force the SmartThreadPool to shutdown
935 /// </summary>
936 public void Shutdown()
937 {
938 Shutdown(true, 0);
939 }
940
941 /// <summary>
942 /// Force the SmartThreadPool to shutdown with timeout
943 /// </summary>
944 public void Shutdown(bool forceAbort, TimeSpan timeout)
945 {
946 Shutdown(forceAbort, (int)timeout.TotalMilliseconds);
947 }
948
949 /// <summary>
950 /// Empties the queue of work items and abort the threads in the pool.
951 /// </summary>
952 public void Shutdown(bool forceAbort, int millisecondsTimeout)
953 {
954 ValidateNotDisposed();
955
956 ISTPInstancePerformanceCounters pcs = _windowsPCs;
957
958 if (NullSTPInstancePerformanceCounters.Instance != _windowsPCs)
959 {
960 // Set the _pcs to "null" to stop updating the performance
961 // counters
962 _windowsPCs = NullSTPInstancePerformanceCounters.Instance;
963
964 pcs.Dispose();
965 }
966
967 Thread [] threads;
968 lock(_workerThreads.SyncRoot)
969 {
970 // Shutdown the work items queue
971 _workItemsQueue.Dispose();
972
973 // Signal the threads to exit
974 _shutdown = true;
975 _shuttingDownEvent.Set();
976
977 // Make a copy of the threads' references in the pool
978 threads = new Thread [_workerThreads.Count];
979 _workerThreads.Keys.CopyTo(threads, 0);
980 }
981
982 int millisecondsLeft = millisecondsTimeout;
983 Stopwatch stopwatch = Stopwatch.StartNew();
984 //DateTime start = DateTime.UtcNow;
985 bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout);
986 bool timeout = false;
987
988 // Each iteration we update the time left for the timeout.
989 foreach(Thread thread in threads)
990 {
991 // Join don't work with negative numbers
992 if (!waitInfinitely && (millisecondsLeft < 0))
993 {
994 timeout = true;
995 break;
996 }
997
998 // Wait for the thread to terminate
999 bool success = thread.Join(millisecondsLeft);
1000 if(!success)
1001 {
1002 timeout = true;
1003 break;
1004 }
1005
1006 if(!waitInfinitely)
1007 {
1008 // Update the time left to wait
1009 //TimeSpan ts = DateTime.UtcNow - start;
1010 millisecondsLeft = millisecondsTimeout - (int)stopwatch.ElapsedMilliseconds;
1011 }
1012 }
1013
1014 if (timeout && forceAbort)
1015 {
1016 // Abort the threads in the pool
1017 foreach(Thread thread in threads)
1018 {
1019
1020 if ((thread != null)
1021#if !(_WINDOWS_CE)
1022 && thread.IsAlive
1023#endif
1024 )
1025 {
1026 try
1027 {
1028 thread.Abort(); // Shutdown
1029 }
1030 catch(SecurityException e)
1031 {
1032 e.GetHashCode();
1033 }
1034 catch(ThreadStateException ex)
1035 {
1036 ex.GetHashCode();
1037 // In case the thread has been terminated
1038 // after the check if it is alive.
1039 }
1040 }
1041 }
1042 }
1043 }
1044
1045 /// <summary>
1046 /// Wait for all work items to complete
1047 /// </summary>
1048 /// <param name="waitableResults">Array of work item result objects</param>
1049 /// <returns>
1050 /// true when every work item in workItemResults has completed; otherwise false.
1051 /// </returns>
1052 public static bool WaitAll(
1053 IWaitableResult [] waitableResults)
1054 {
1055 return WaitAll(waitableResults, Timeout.Infinite, true);
1056 }
1057
1058 /// <summary>
1059 /// Wait for all work items to complete
1060 /// </summary>
1061 /// <param name="waitableResults">Array of work item result objects</param>
1062 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
1063 /// <param name="exitContext">
1064 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1065 /// </param>
1066 /// <returns>
1067 /// true when every work item in workItemResults has completed; otherwise false.
1068 /// </returns>
1069 public static bool WaitAll(
1070 IWaitableResult [] waitableResults,
1071 TimeSpan timeout,
1072 bool exitContext)
1073 {
1074 return WaitAll(waitableResults, (int)timeout.TotalMilliseconds, exitContext);
1075 }
1076
1077 /// <summary>
1078 /// Wait for all work items to complete
1079 /// </summary>
1080 /// <param name="waitableResults">Array of work item result objects</param>
1081 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
1082 /// <param name="exitContext">
1083 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1084 /// </param>
1085 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
1086 /// <returns>
1087 /// true when every work item in workItemResults has completed; otherwise false.
1088 /// </returns>
1089 public static bool WaitAll(
1090 IWaitableResult[] waitableResults,
1091 TimeSpan timeout,
1092 bool exitContext,
1093 WaitHandle cancelWaitHandle)
1094 {
1095 return WaitAll(waitableResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
1096 }
1097
1098 /// <summary>
1099 /// Wait for all work items to complete
1100 /// </summary>
1101 /// <param name="waitableResults">Array of work item result objects</param>
1102 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
1103 /// <param name="exitContext">
1104 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1105 /// </param>
1106 /// <returns>
1107 /// true when every work item in workItemResults has completed; otherwise false.
1108 /// </returns>
1109 public static bool WaitAll(
1110 IWaitableResult [] waitableResults,
1111 int millisecondsTimeout,
1112 bool exitContext)
1113 {
1114 return WorkItem.WaitAll(waitableResults, millisecondsTimeout, exitContext, null);
1115 }
1116
1117 /// <summary>
1118 /// Wait for all work items to complete
1119 /// </summary>
1120 /// <param name="waitableResults">Array of work item result objects</param>
1121 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
1122 /// <param name="exitContext">
1123 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1124 /// </param>
1125 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
1126 /// <returns>
1127 /// true when every work item in workItemResults has completed; otherwise false.
1128 /// </returns>
1129 public static bool WaitAll(
1130 IWaitableResult[] waitableResults,
1131 int millisecondsTimeout,
1132 bool exitContext,
1133 WaitHandle cancelWaitHandle)
1134 {
1135 return WorkItem.WaitAll(waitableResults, millisecondsTimeout, exitContext, cancelWaitHandle);
1136 }
1137
1138
1139 /// <summary>
1140 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
1141 /// </summary>
1142 /// <param name="waitableResults">Array of work item result objects</param>
1143 /// <returns>
1144 /// The array index of the work item result that satisfied the wait, or WaitTimeout if any of the work items has been canceled.
1145 /// </returns>
1146 public static int WaitAny(
1147 IWaitableResult [] waitableResults)
1148 {
1149 return WaitAny(waitableResults, Timeout.Infinite, true);
1150 }
1151
1152 /// <summary>
1153 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
1154 /// </summary>
1155 /// <param name="waitableResults">Array of work item result objects</param>
1156 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
1157 /// <param name="exitContext">
1158 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1159 /// </param>
1160 /// <returns>
1161 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
1162 /// </returns>
1163 public static int WaitAny(
1164 IWaitableResult[] waitableResults,
1165 TimeSpan timeout,
1166 bool exitContext)
1167 {
1168 return WaitAny(waitableResults, (int)timeout.TotalMilliseconds, exitContext);
1169 }
1170
1171 /// <summary>
1172 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
1173 /// </summary>
1174 /// <param name="waitableResults">Array of work item result objects</param>
1175 /// <param name="timeout">The number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely. </param>
1176 /// <param name="exitContext">
1177 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1178 /// </param>
1179 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
1180 /// <returns>
1181 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
1182 /// </returns>
1183 public static int WaitAny(
1184 IWaitableResult [] waitableResults,
1185 TimeSpan timeout,
1186 bool exitContext,
1187 WaitHandle cancelWaitHandle)
1188 {
1189 return WaitAny(waitableResults, (int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
1190 }
1191
1192 /// <summary>
1193 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
1194 /// </summary>
1195 /// <param name="waitableResults">Array of work item result objects</param>
1196 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
1197 /// <param name="exitContext">
1198 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1199 /// </param>
1200 /// <returns>
1201 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
1202 /// </returns>
1203 public static int WaitAny(
1204 IWaitableResult [] waitableResults,
1205 int millisecondsTimeout,
1206 bool exitContext)
1207 {
1208 return WorkItem.WaitAny(waitableResults, millisecondsTimeout, exitContext, null);
1209 }
1210
1211 /// <summary>
1212 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
1213 /// </summary>
1214 /// <param name="waitableResults">Array of work item result objects</param>
1215 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
1216 /// <param name="exitContext">
1217 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
1218 /// </param>
1219 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
1220 /// <returns>
1221 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
1222 /// </returns>
1223 public static int WaitAny(
1224 IWaitableResult [] waitableResults,
1225 int millisecondsTimeout,
1226 bool exitContext,
1227 WaitHandle cancelWaitHandle)
1228 {
1229 return WorkItem.WaitAny(waitableResults, millisecondsTimeout, exitContext, cancelWaitHandle);
1230 }
1231
1232 /// <summary>
1233 /// Creates a new WorkItemsGroup.
1234 /// </summary>
1235 /// <param name="concurrency">The number of work items that can be run concurrently</param>
1236 /// <returns>A reference to the WorkItemsGroup</returns>
1237 public IWorkItemsGroup CreateWorkItemsGroup(int concurrency)
1238 {
1239 IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, _stpStartInfo);
1240 return workItemsGroup;
1241 }
1242
1243 /// <summary>
1244 /// Creates a new WorkItemsGroup.
1245 /// </summary>
1246 /// <param name="concurrency">The number of work items that can be run concurrently</param>
1247 /// <param name="wigStartInfo">A WorkItemsGroup configuration that overrides the default behavior</param>
1248 /// <returns>A reference to the WorkItemsGroup</returns>
1249 public IWorkItemsGroup CreateWorkItemsGroup(int concurrency, WIGStartInfo wigStartInfo)
1250 {
1251 IWorkItemsGroup workItemsGroup = new WorkItemsGroup(this, concurrency, wigStartInfo);
1252 return workItemsGroup;
1253 }
1254
1255 #region Fire Thread's Events
1256
1257 private void FireOnThreadInitialization()
1258 {
1259 if (null != _onThreadInitialization)
1260 {
1261 foreach (ThreadInitializationHandler tih in _onThreadInitialization.GetInvocationList())
1262 {
1263 try
1264 {
1265 tih();
1266 }
1267 catch (Exception e)
1268 {
1269 e.GetHashCode();
1270 Debug.Assert(false);
1271 throw;
1272 }
1273 }
1274 }
1275 }
1276
1277 private void FireOnThreadTermination()
1278 {
1279 if (null != _onThreadTermination)
1280 {
1281 foreach (ThreadTerminationHandler tth in _onThreadTermination.GetInvocationList())
1282 {
1283 try
1284 {
1285 tth();
1286 }
1287 catch (Exception e)
1288 {
1289 e.GetHashCode();
1290 Debug.Assert(false);
1291 throw;
1292 }
1293 }
1294 }
1295 }
1296
1297 #endregion
1298
1299 /// <summary>
1300 /// This event is fired when a thread is created.
1301 /// Use it to initialize a thread before the work items use it.
1302 /// </summary>
1303 public event ThreadInitializationHandler OnThreadInitialization
1304 {
1305 add { _onThreadInitialization += value; }
1306 remove { _onThreadInitialization -= value; }
1307 }
1308
1309 /// <summary>
1310 /// This event is fired when a thread is terminating.
1311 /// Use it for cleanup.
1312 /// </summary>
1313 public event ThreadTerminationHandler OnThreadTermination
1314 {
1315 add { _onThreadTermination += value; }
1316 remove { _onThreadTermination -= value; }
1317 }
1318
1319
1320 internal void CancelAbortWorkItemsGroup(WorkItemsGroup wig)
1321 {
1322 foreach (ThreadEntry threadEntry in _workerThreads.Values)
1323 {
1324 WorkItem workItem = threadEntry.CurrentWorkItem;
1325 if (null != workItem &&
1326 workItem.WasQueuedBy(wig) &&
1327 !workItem.IsCanceled)
1328 {
1329 threadEntry.CurrentWorkItem.GetWorkItemResult().Cancel(true);
1330 }
1331 }
1332 }
1333
1334
1335
1336 #endregion
1337
1338 #region Properties
1339
1340 /// <summary>
1341 /// Get/Set the lower limit of threads in the pool.
1342 /// </summary>
1343 public int MinThreads
1344 {
1345 get
1346 {
1347 ValidateNotDisposed();
1348 return _stpStartInfo.MinWorkerThreads;
1349 }
1350 set
1351 {
1352 Debug.Assert(value >= 0);
1353 Debug.Assert(value <= _stpStartInfo.MaxWorkerThreads);
1354 if (_stpStartInfo.MaxWorkerThreads < value)
1355 {
1356 _stpStartInfo.MaxWorkerThreads = value;
1357 }
1358 _stpStartInfo.MinWorkerThreads = value;
1359 StartOptimalNumberOfThreads();
1360 }
1361 }
1362
1363 /// <summary>
1364 /// Get/Set the upper limit of threads in the pool.
1365 /// </summary>
1366 public int MaxThreads
1367 {
1368 get
1369 {
1370 ValidateNotDisposed();
1371 return _stpStartInfo.MaxWorkerThreads;
1372 }
1373
1374 set
1375 {
1376 Debug.Assert(value > 0);
1377 Debug.Assert(value >= _stpStartInfo.MinWorkerThreads);
1378 if (_stpStartInfo.MinWorkerThreads > value)
1379 {
1380 _stpStartInfo.MinWorkerThreads = value;
1381 }
1382 _stpStartInfo.MaxWorkerThreads = value;
1383 StartOptimalNumberOfThreads();
1384 }
1385 }
1386 /// <summary>
1387 /// Get the number of threads in the thread pool.
1388 /// Should be between the lower and the upper limits.
1389 /// </summary>
1390 public int ActiveThreads
1391 {
1392 get
1393 {
1394 ValidateNotDisposed();
1395 return _workerThreads.Count;
1396 }
1397 }
1398
1399 /// <summary>
1400 /// Get the number of busy (not idle) threads in the thread pool.
1401 /// </summary>
1402 public int InUseThreads
1403 {
1404 get
1405 {
1406 ValidateNotDisposed();
1407 return _inUseWorkerThreads;
1408 }
1409 }
1410
1411 /// <summary>
1412 /// Returns true if the current running work item has been cancelled.
1413 /// Must be used within the work item's callback method.
1414 /// The work item should sample this value in order to know if it
1415 /// needs to quit before its completion.
1416 /// </summary>
1417 public static bool IsWorkItemCanceled
1418 {
1419 get
1420 {
1421 return CurrentThreadEntry.CurrentWorkItem.IsCanceled;
1422 }
1423 }
1424
1425 /// <summary>
1426 /// Checks if the work item has been cancelled, and if yes then abort the thread.
1427 /// Can be used with Cancel and timeout
1428 /// </summary>
1429 public static void AbortOnWorkItemCancel()
1430 {
1431 if (IsWorkItemCanceled)
1432 {
1433 Thread.CurrentThread.Abort();
1434 }
1435 }
1436
1437 /// <summary>
1438 /// Thread Pool start information (readonly)
1439 /// </summary>
1440 public STPStartInfo STPStartInfo
1441 {
1442 get
1443 {
1444 return _stpStartInfo.AsReadOnly();
1445 }
1446 }
1447
1448 public bool IsShuttingdown
1449 {
1450 get { return _shutdown; }
1451 }
1452
1453 /// <summary>
1454 /// Return the local calculated performance counters
1455 /// Available only if STPStartInfo.EnableLocalPerformanceCounters is true.
1456 /// </summary>
1457 public ISTPPerformanceCountersReader PerformanceCountersReader
1458 {
1459 get { return (ISTPPerformanceCountersReader)_localPCs; }
1460 }
1461
1462 #endregion
1463
1464 #region IDisposable Members
1465
1466 public void Dispose()
1467 {
1468 if (!_isDisposed)
1469 {
1470 if (!_shutdown)
1471 {
1472 Shutdown();
1473 }
1474
1475 if (null != _shuttingDownEvent)
1476 {
1477 _shuttingDownEvent.Close();
1478 _shuttingDownEvent = null;
1479 }
1480 _workerThreads.Clear();
1481
1482 if (null != _isIdleWaitHandle)
1483 {
1484 _isIdleWaitHandle.Close();
1485 _isIdleWaitHandle = null;
1486 }
1487
1488 if (_stpStartInfo.EnableLocalPerformanceCounters)
1489 _localPCs.Dispose();
1490
1491 _isDisposed = true;
1492 }
1493 }
1494
1495 private void ValidateNotDisposed()
1496 {
1497 if(_isDisposed)
1498 {
1499 throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
1500 }
1501 }
1502 #endregion
1503
1504 #region WorkItemsGroupBase Overrides
1505
1506 /// <summary>
1507 /// Get/Set the maximum number of work items that execute cocurrency on the thread pool
1508 /// </summary>
1509 public override int Concurrency
1510 {
1511 get { return MaxThreads; }
1512 set { MaxThreads = value; }
1513 }
1514
1515 /// <summary>
1516 /// Get the number of work items in the queue.
1517 /// </summary>
1518 public override int WaitingCallbacks
1519 {
1520 get
1521 {
1522 ValidateNotDisposed();
1523 return _workItemsQueue.Count;
1524 }
1525 }
1526
1527 /// <summary>
1528 /// Get an array with all the state objects of the currently running items.
1529 /// The array represents a snap shot and impact performance.
1530 /// </summary>
1531 public override object[] GetStates()
1532 {
1533 object[] states = _workItemsQueue.GetStates();
1534 return states;
1535 }
1536
1537 /// <summary>
1538 /// WorkItemsGroup start information (readonly)
1539 /// </summary>
1540 public override WIGStartInfo WIGStartInfo
1541 {
1542 get { return _stpStartInfo.AsReadOnly(); }
1543 }
1544
1545 /// <summary>
1546 /// Start the thread pool if it was started suspended.
1547 /// If it is already running, this method is ignored.
1548 /// </summary>
1549 public override void Start()
1550 {
1551 if (!_isSuspended)
1552 {
1553 return;
1554 }
1555 _isSuspended = false;
1556
1557 ICollection workItemsGroups = _workItemsGroups.Values;
1558 foreach (WorkItemsGroup workItemsGroup in workItemsGroups)
1559 {
1560 workItemsGroup.OnSTPIsStarting();
1561 }
1562
1563 StartOptimalNumberOfThreads();
1564 }
1565
1566 /// <summary>
1567 /// Cancel all work items using thread abortion
1568 /// </summary>
1569 /// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param>
1570 public override void Cancel(bool abortExecution)
1571 {
1572 _canceledSmartThreadPool.IsCanceled = true;
1573 _canceledSmartThreadPool = new CanceledWorkItemsGroup();
1574
1575 ICollection workItemsGroups = _workItemsGroups.Values;
1576 foreach (WorkItemsGroup workItemsGroup in workItemsGroups)
1577 {
1578 workItemsGroup.Cancel(abortExecution);
1579 }
1580
1581 if (abortExecution)
1582 {
1583 foreach (ThreadEntry threadEntry in _workerThreads.Values)
1584 {
1585 WorkItem workItem = threadEntry.CurrentWorkItem;
1586 if (null != workItem &&
1587 threadEntry.AssociatedSmartThreadPool == this &&
1588 !workItem.IsCanceled)
1589 {
1590 threadEntry.CurrentWorkItem.GetWorkItemResult().Cancel(true);
1591 }
1592 }
1593 }
1594 }
1595
1596 /// <summary>
1597 /// Wait for the thread pool to be idle
1598 /// </summary>
1599 public override bool WaitForIdle(int millisecondsTimeout)
1600 {
1601 ValidateWaitForIdle();
1602 return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
1603 }
1604
1605 /// <summary>
1606 /// This event is fired when all work items are completed.
1607 /// (When IsIdle changes to true)
1608 /// This event only work on WorkItemsGroup. On SmartThreadPool
1609 /// it throws the NotImplementedException.
1610 /// </summary>
1611 public override event WorkItemsGroupIdleHandler OnIdle
1612 {
1613 add
1614 {
1615 throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature.");
1616 //_onIdle += value;
1617 }
1618 remove
1619 {
1620 throw new NotImplementedException("This event is not implemented in the SmartThreadPool class. Please create a WorkItemsGroup in order to use this feature.");
1621 //_onIdle -= value;
1622 }
1623 }
1624
1625 internal override void PreQueueWorkItem()
1626 {
1627 ValidateNotDisposed();
1628 }
1629
1630 #endregion
1631
1632 #region Join, Choice, Pipe, etc.
1633
1634 /// <summary>
1635 /// Executes all actions in parallel.
1636 /// Returns when they all finish.
1637 /// </summary>
1638 /// <param name="actions">Actions to execute</param>
1639 public void Join(IEnumerable<Action> actions)
1640 {
1641 WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
1642 IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(int.MaxValue, wigStartInfo);
1643 foreach (Action action in actions)
1644 {
1645 workItemsGroup.QueueWorkItem(action);
1646 }
1647 workItemsGroup.Start();
1648 workItemsGroup.WaitForIdle();
1649 }
1650
1651 /// <summary>
1652 /// Executes all actions in parallel.
1653 /// Returns when they all finish.
1654 /// </summary>
1655 /// <param name="actions">Actions to execute</param>
1656 public void Join(params Action[] actions)
1657 {
1658 Join((IEnumerable<Action>)actions);
1659 }
1660
1661 private class ChoiceIndex
1662 {
1663 public int _index = -1;
1664 }
1665
1666 /// <summary>
1667 /// Executes all actions in parallel
1668 /// Returns when the first one completes
1669 /// </summary>
1670 /// <param name="actions">Actions to execute</param>
1671 public int Choice(IEnumerable<Action> actions)
1672 {
1673 WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
1674 IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(int.MaxValue, wigStartInfo);
1675
1676 ManualResetEvent anActionCompleted = new ManualResetEvent(false);
1677
1678 ChoiceIndex choiceIndex = new ChoiceIndex();
1679
1680 int i = 0;
1681 foreach (Action action in actions)
1682 {
1683 Action act = action;
1684 int value = i;
1685 workItemsGroup.QueueWorkItem(() => { act(); Interlocked.CompareExchange(ref choiceIndex._index, value, -1); anActionCompleted.Set(); });
1686 ++i;
1687 }
1688 workItemsGroup.Start();
1689 anActionCompleted.WaitOne();
1690 anActionCompleted.Dispose();
1691
1692 return choiceIndex._index;
1693 }
1694
1695 /// <summary>
1696 /// Executes all actions in parallel
1697 /// Returns when the first one completes
1698 /// </summary>
1699 /// <param name="actions">Actions to execute</param>
1700 public int Choice(params Action[] actions)
1701 {
1702 return Choice((IEnumerable<Action>)actions);
1703 }
1704
1705 /// <summary>
1706 /// Executes actions in sequence asynchronously.
1707 /// Returns immediately.
1708 /// </summary>
1709 /// <param name="pipeState">A state context that passes </param>
1710 /// <param name="actions">Actions to execute in the order they should run</param>
1711 public void Pipe<T>(T pipeState, IEnumerable<Action<T>> actions)
1712 {
1713 WIGStartInfo wigStartInfo = new WIGStartInfo { StartSuspended = true };
1714 IWorkItemsGroup workItemsGroup = CreateWorkItemsGroup(1, wigStartInfo);
1715 foreach (Action<T> action in actions)
1716 {
1717 Action<T> act = action;
1718 workItemsGroup.QueueWorkItem(() => act(pipeState));
1719 }
1720 workItemsGroup.Start();
1721 workItemsGroup.WaitForIdle();
1722 }
1723
1724 /// <summary>
1725 /// Executes actions in sequence asynchronously.
1726 /// Returns immediately.
1727 /// </summary>
1728 /// <param name="pipeState"></param>
1729 /// <param name="actions">Actions to execute in the order they should run</param>
1730 public void Pipe<T>(T pipeState, params Action<T>[] actions)
1731 {
1732 Pipe(pipeState, (IEnumerable<Action<T>>)actions);
1733 }
1734 #endregion
1735 }
1736 #endregion
1737}
diff --git a/ThirdParty/SmartThreadPool/SynchronizedDictionary.cs b/ThirdParty/SmartThreadPool/SynchronizedDictionary.cs
new file mode 100644
index 0000000..0cce19f
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/SynchronizedDictionary.cs
@@ -0,0 +1,89 @@
1using System.Collections.Generic;
2
3namespace Amib.Threading.Internal
4{
5 internal class SynchronizedDictionary<TKey, TValue>
6 {
7 private readonly Dictionary<TKey, TValue> _dictionary;
8 private readonly object _lock;
9
10 public SynchronizedDictionary()
11 {
12 _lock = new object();
13 _dictionary = new Dictionary<TKey, TValue>();
14 }
15
16 public int Count
17 {
18 get { return _dictionary.Count; }
19 }
20
21 public bool Contains(TKey key)
22 {
23 lock (_lock)
24 {
25 return _dictionary.ContainsKey(key);
26 }
27 }
28
29 public void Remove(TKey key)
30 {
31 lock (_lock)
32 {
33 _dictionary.Remove(key);
34 }
35 }
36
37 public object SyncRoot
38 {
39 get { return _lock; }
40 }
41
42 public TValue this[TKey key]
43 {
44 get
45 {
46 lock (_lock)
47 {
48 return _dictionary[key];
49 }
50 }
51 set
52 {
53 lock (_lock)
54 {
55 _dictionary[key] = value;
56 }
57 }
58 }
59
60 public Dictionary<TKey, TValue>.KeyCollection Keys
61 {
62 get
63 {
64 lock (_lock)
65 {
66 return _dictionary.Keys;
67 }
68 }
69 }
70
71 public Dictionary<TKey, TValue>.ValueCollection Values
72 {
73 get
74 {
75 lock (_lock)
76 {
77 return _dictionary.Values;
78 }
79 }
80 }
81 public void Clear()
82 {
83 lock (_lock)
84 {
85 _dictionary.Clear();
86 }
87 }
88 }
89}
diff --git a/ThirdParty/SmartThreadPool/WIGStartInfo.cs b/ThirdParty/SmartThreadPool/WIGStartInfo.cs
new file mode 100644
index 0000000..756ac1f
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/WIGStartInfo.cs
@@ -0,0 +1,171 @@
1using System;
2
3namespace Amib.Threading
4{
5 /// <summary>
6 /// Summary description for WIGStartInfo.
7 /// </summary>
8 public class WIGStartInfo
9 {
10 private bool _useCallerCallContext;
11 private bool _useCallerHttpContext;
12 private bool _disposeOfStateObjects;
13 private CallToPostExecute _callToPostExecute;
14 private PostExecuteWorkItemCallback _postExecuteWorkItemCallback;
15 private bool _startSuspended;
16 private WorkItemPriority _workItemPriority;
17 private bool _fillStateWithArgs;
18
19 protected bool _readOnly;
20
21 public WIGStartInfo()
22 {
23 _fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs;
24 _workItemPriority = SmartThreadPool.DefaultWorkItemPriority;
25 _startSuspended = SmartThreadPool.DefaultStartSuspended;
26 _postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
27 _callToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
28 _disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
29 _useCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
30 _useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
31 }
32
33 public WIGStartInfo(WIGStartInfo wigStartInfo)
34 {
35 _useCallerCallContext = wigStartInfo.UseCallerCallContext;
36 _useCallerHttpContext = wigStartInfo.UseCallerHttpContext;
37 _disposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
38 _callToPostExecute = wigStartInfo.CallToPostExecute;
39 _postExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
40 _workItemPriority = wigStartInfo.WorkItemPriority;
41 _startSuspended = wigStartInfo.StartSuspended;
42 _fillStateWithArgs = wigStartInfo.FillStateWithArgs;
43 }
44
45 protected void ThrowIfReadOnly()
46 {
47 if (_readOnly)
48 {
49 throw new NotSupportedException("This is a readonly instance and set is not supported");
50 }
51 }
52
53 /// <summary>
54 /// Get/Set if to use the caller's security context
55 /// </summary>
56 public virtual bool UseCallerCallContext
57 {
58 get { return _useCallerCallContext; }
59 set
60 {
61 ThrowIfReadOnly();
62 _useCallerCallContext = value;
63 }
64 }
65
66
67 /// <summary>
68 /// Get/Set if to use the caller's HTTP context
69 /// </summary>
70 public virtual bool UseCallerHttpContext
71 {
72 get { return _useCallerHttpContext; }
73 set
74 {
75 ThrowIfReadOnly();
76 _useCallerHttpContext = value;
77 }
78 }
79
80
81 /// <summary>
82 /// Get/Set if to dispose of the state object of a work item
83 /// </summary>
84 public virtual bool DisposeOfStateObjects
85 {
86 get { return _disposeOfStateObjects; }
87 set
88 {
89 ThrowIfReadOnly();
90 _disposeOfStateObjects = value;
91 }
92 }
93
94
95 /// <summary>
96 /// Get/Set the run the post execute options
97 /// </summary>
98 public virtual CallToPostExecute CallToPostExecute
99 {
100 get { return _callToPostExecute; }
101 set
102 {
103 ThrowIfReadOnly();
104 _callToPostExecute = value;
105 }
106 }
107
108
109 /// <summary>
110 /// Get/Set the default post execute callback
111 /// </summary>
112 public virtual PostExecuteWorkItemCallback PostExecuteWorkItemCallback
113 {
114 get { return _postExecuteWorkItemCallback; }
115 set
116 {
117 ThrowIfReadOnly();
118 _postExecuteWorkItemCallback = value;
119 }
120 }
121
122
123 /// <summary>
124 /// Get/Set if the work items execution should be suspended until the Start()
125 /// method is called.
126 /// </summary>
127 public virtual bool StartSuspended
128 {
129 get { return _startSuspended; }
130 set
131 {
132 ThrowIfReadOnly();
133 _startSuspended = value;
134 }
135 }
136
137
138 /// <summary>
139 /// Get/Set the default priority that a work item gets when it is enqueued
140 /// </summary>
141 public virtual WorkItemPriority WorkItemPriority
142 {
143 get { return _workItemPriority; }
144 set { _workItemPriority = value; }
145 }
146
147 /// <summary>
148 /// Get/Set the if QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt; fill the
149 /// arguments as an object array into the state of the work item.
150 /// The arguments can be access later by IWorkItemResult.State.
151 /// </summary>
152 public virtual bool FillStateWithArgs
153 {
154 get { return _fillStateWithArgs; }
155 set
156 {
157 ThrowIfReadOnly();
158 _fillStateWithArgs = value;
159 }
160 }
161
162 /// <summary>
163 /// Get a readonly version of this WIGStartInfo
164 /// </summary>
165 /// <returns>Returns a readonly reference to this WIGStartInfoRO</returns>
166 public WIGStartInfo AsReadOnly()
167 {
168 return new WIGStartInfo(this) { _readOnly = true };
169 }
170 }
171}
diff --git a/ThirdParty/SmartThreadPool/WorkItem.WorkItemResult.cs b/ThirdParty/SmartThreadPool/WorkItem.WorkItemResult.cs
new file mode 100644
index 0000000..435a14b
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/WorkItem.WorkItemResult.cs
@@ -0,0 +1,190 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5
6namespace Amib.Threading.Internal
7{
8 public partial class WorkItem
9 {
10 #region WorkItemResult class
11
12 private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult, IInternalWaitableResult
13 {
14 /// <summary>
15 /// A back reference to the work item
16 /// </summary>
17 private readonly WorkItem _workItem;
18
19 public WorkItemResult(WorkItem workItem)
20 {
21 _workItem = workItem;
22 }
23
24 internal WorkItem GetWorkItem()
25 {
26 return _workItem;
27 }
28
29 #region IWorkItemResult Members
30
31 public bool IsCompleted
32 {
33 get
34 {
35 return _workItem.IsCompleted;
36 }
37 }
38
39 public bool IsCanceled
40 {
41 get
42 {
43 return _workItem.IsCanceled;
44 }
45 }
46
47 public object GetResult()
48 {
49 return _workItem.GetResult(Timeout.Infinite, true, null);
50 }
51
52 public object GetResult(int millisecondsTimeout, bool exitContext)
53 {
54 return _workItem.GetResult(millisecondsTimeout, exitContext, null);
55 }
56
57 public object GetResult(TimeSpan timeout, bool exitContext)
58 {
59 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null);
60 }
61
62 public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
63 {
64 return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
65 }
66
67 public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
68 {
69 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
70 }
71
72 public object GetResult(out Exception e)
73 {
74 return _workItem.GetResult(Timeout.Infinite, true, null, out e);
75 }
76
77 public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
78 {
79 return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e);
80 }
81
82 public object GetResult(TimeSpan timeout, bool exitContext, out Exception e)
83 {
84 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e);
85 }
86
87 public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
88 {
89 return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
90 }
91
92 public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
93 {
94 return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e);
95 }
96
97 public bool Cancel()
98 {
99 return Cancel(false);
100 }
101
102 public bool Cancel(bool abortExecution)
103 {
104 return _workItem.Cancel(abortExecution);
105 }
106
107 public object State
108 {
109 get
110 {
111 return _workItem._state;
112 }
113 }
114
115 public WorkItemPriority WorkItemPriority
116 {
117 get
118 {
119 return _workItem._workItemInfo.WorkItemPriority;
120 }
121 }
122
123 /// <summary>
124 /// Return the result, same as GetResult()
125 /// </summary>
126 public object Result
127 {
128 get { return GetResult(); }
129 }
130
131 /// <summary>
132 /// Returns the exception if occured otherwise returns null.
133 /// This value is valid only after the work item completed,
134 /// before that it is always null.
135 /// </summary>
136 public object Exception
137 {
138 get { return _workItem._exception; }
139 }
140
141 #endregion
142
143 #region IInternalWorkItemResult Members
144
145 public event WorkItemStateCallback OnWorkItemStarted
146 {
147 add
148 {
149 _workItem.OnWorkItemStarted += value;
150 }
151 remove
152 {
153 _workItem.OnWorkItemStarted -= value;
154 }
155 }
156
157
158 public event WorkItemStateCallback OnWorkItemCompleted
159 {
160 add
161 {
162 _workItem.OnWorkItemCompleted += value;
163 }
164 remove
165 {
166 _workItem.OnWorkItemCompleted -= value;
167 }
168 }
169
170 #endregion
171
172 #region IInternalWorkItemResult Members
173
174 public IWorkItemResult GetWorkItemResult()
175 {
176 return this;
177 }
178
179 public IWorkItemResult<TResult> GetWorkItemResultT<TResult>()
180 {
181 return new WorkItemResultTWrapper<TResult>(this);
182 }
183
184 #endregion
185 }
186
187 #endregion
188
189 }
190}
diff --git a/ThirdParty/SmartThreadPool/WorkItem.cs b/ThirdParty/SmartThreadPool/WorkItem.cs
new file mode 100644
index 0000000..edb8ac0
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/WorkItem.cs
@@ -0,0 +1,1002 @@
1using System;
2using System.Threading;
3using System.Diagnostics;
4
5namespace Amib.Threading.Internal
6{
7 /// <summary>
8 /// Holds a callback delegate and the state for that delegate.
9 /// </summary>
10 public partial class WorkItem : IHasWorkItemPriority
11 {
12 #region WorkItemState enum
13
14 /// <summary>
15 /// Indicates the state of the work item in the thread pool
16 /// </summary>
17 private enum WorkItemState
18 {
19 InQueue = 0, // Nexts: InProgress, Canceled
20 InProgress = 1, // Nexts: Completed, Canceled
21 Completed = 2, // Stays Completed
22 Canceled = 3, // Stays Canceled
23 }
24
25 private static bool IsValidStatesTransition(WorkItemState currentState, WorkItemState nextState)
26 {
27 bool valid = false;
28
29 switch (currentState)
30 {
31 case WorkItemState.InQueue:
32 valid = (WorkItemState.InProgress == nextState) || (WorkItemState.Canceled == nextState);
33 break;
34 case WorkItemState.InProgress:
35 valid = (WorkItemState.Completed == nextState) || (WorkItemState.Canceled == nextState);
36 break;
37 case WorkItemState.Completed:
38 case WorkItemState.Canceled:
39 // Cannot be changed
40 break;
41 default:
42 // Unknown state
43 Debug.Assert(false);
44 break;
45 }
46
47 return valid;
48 }
49
50 #endregion
51
52 #region Fields
53
54 /// <summary>
55 /// Callback delegate for the callback.
56 /// </summary>
57 private readonly WorkItemCallback _callback;
58
59 /// <summary>
60 /// State with which to call the callback delegate.
61 /// </summary>
62 private object _state;
63
64#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
65 /// <summary>
66 /// Stores the caller's context
67 /// </summary>
68 private readonly CallerThreadContext _callerContext;
69#endif
70 /// <summary>
71 /// Holds the result of the mehtod
72 /// </summary>
73 private object _result;
74
75 /// <summary>
76 /// Hold the exception if the method threw it
77 /// </summary>
78 private Exception _exception;
79
80 /// <summary>
81 /// Hold the state of the work item
82 /// </summary>
83 private WorkItemState _workItemState;
84
85 /// <summary>
86 /// A ManualResetEvent to indicate that the result is ready
87 /// </summary>
88 private ManualResetEvent _workItemCompleted;
89
90 /// <summary>
91 /// A reference count to the _workItemCompleted.
92 /// When it reaches to zero _workItemCompleted is Closed
93 /// </summary>
94 private int _workItemCompletedRefCount;
95
96 /// <summary>
97 /// Represents the result state of the work item
98 /// </summary>
99 private readonly WorkItemResult _workItemResult;
100
101 /// <summary>
102 /// Work item info
103 /// </summary>
104 private readonly WorkItemInfo _workItemInfo;
105
106 /// <summary>
107 /// Called when the WorkItem starts
108 /// </summary>
109 private event WorkItemStateCallback _workItemStartedEvent;
110
111 /// <summary>
112 /// Called when the WorkItem completes
113 /// </summary>
114 private event WorkItemStateCallback _workItemCompletedEvent;
115
116 /// <summary>
117 /// A reference to an object that indicates whatever the
118 /// WorkItemsGroup has been canceled
119 /// </summary>
120 private CanceledWorkItemsGroup _canceledWorkItemsGroup = CanceledWorkItemsGroup.NotCanceledWorkItemsGroup;
121
122 /// <summary>
123 /// A reference to an object that indicates whatever the
124 /// SmartThreadPool has been canceled
125 /// </summary>
126 private CanceledWorkItemsGroup _canceledSmartThreadPool = CanceledWorkItemsGroup.NotCanceledWorkItemsGroup;
127
128 /// <summary>
129 /// The work item group this work item belong to.
130 /// </summary>
131 private readonly IWorkItemsGroup _workItemsGroup;
132
133 /// <summary>
134 /// The thread that executes this workitem.
135 /// This field is available for the period when the work item is executed, before and after it is null.
136 /// </summary>
137 private Thread _executingThread;
138
139 /// <summary>
140 /// The absulote time when the work item will be timeout
141 /// </summary>
142 private long _expirationTime;
143
144 #region Performance Counter fields
145
146
147
148
149 /// <summary>
150 /// Stores how long the work item waited on the stp queue
151 /// </summary>
152 private Stopwatch _waitingOnQueueStopwatch;
153
154 /// <summary>
155 /// Stores how much time it took the work item to execute after it went out of the queue
156 /// </summary>
157 private Stopwatch _processingStopwatch;
158
159 #endregion
160
161 #endregion
162
163 #region Properties
164
165 public TimeSpan WaitingTime
166 {
167 get
168 {
169 return _waitingOnQueueStopwatch.Elapsed;
170 }
171 }
172
173 public TimeSpan ProcessTime
174 {
175 get
176 {
177 return _processingStopwatch.Elapsed;
178 }
179 }
180
181 internal WorkItemInfo WorkItemInfo
182 {
183 get
184 {
185 return _workItemInfo;
186 }
187 }
188
189 #endregion
190
191 #region Construction
192
193 /// <summary>
194 /// Initialize the callback holding object.
195 /// </summary>
196 /// <param name="workItemsGroup">The workItemGroup of the workitem</param>
197 /// <param name="workItemInfo">The WorkItemInfo of te workitem</param>
198 /// <param name="callback">Callback delegate for the callback.</param>
199 /// <param name="state">State with which to call the callback delegate.</param>
200 ///
201 /// We assume that the WorkItem object is created within the thread
202 /// that meant to run the callback
203 public WorkItem(
204 IWorkItemsGroup workItemsGroup,
205 WorkItemInfo workItemInfo,
206 WorkItemCallback callback,
207 object state)
208 {
209 _workItemsGroup = workItemsGroup;
210 _workItemInfo = workItemInfo;
211
212#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
213 if (_workItemInfo.UseCallerCallContext || _workItemInfo.UseCallerHttpContext)
214 {
215 _callerContext = CallerThreadContext.Capture(_workItemInfo.UseCallerCallContext, _workItemInfo.UseCallerHttpContext);
216 }
217#endif
218
219 _callback = callback;
220 _state = state;
221 _workItemResult = new WorkItemResult(this);
222 Initialize();
223 }
224
225 internal void Initialize()
226 {
227 // The _workItemState is changed directly instead of using the SetWorkItemState
228 // method since we don't want to go throught IsValidStateTransition.
229 _workItemState = WorkItemState.InQueue;
230
231 _workItemCompleted = null;
232 _workItemCompletedRefCount = 0;
233 _waitingOnQueueStopwatch = new Stopwatch();
234 _processingStopwatch = new Stopwatch();
235 _expirationTime =
236 _workItemInfo.Timeout > 0 ?
237 DateTime.UtcNow.Ticks + _workItemInfo.Timeout * TimeSpan.TicksPerMillisecond :
238 long.MaxValue;
239 }
240
241 internal bool WasQueuedBy(IWorkItemsGroup workItemsGroup)
242 {
243 return (workItemsGroup == _workItemsGroup);
244 }
245
246
247 #endregion
248
249 #region Methods
250
251 internal CanceledWorkItemsGroup CanceledWorkItemsGroup
252 {
253 get { return _canceledWorkItemsGroup; }
254 set { _canceledWorkItemsGroup = value; }
255 }
256
257 internal CanceledWorkItemsGroup CanceledSmartThreadPool
258 {
259 get { return _canceledSmartThreadPool; }
260 set { _canceledSmartThreadPool = value; }
261 }
262
263 /// <summary>
264 /// Change the state of the work item to in progress if it wasn't canceled.
265 /// </summary>
266 /// <returns>
267 /// Return true on success or false in case the work item was canceled.
268 /// If the work item needs to run a post execute then the method will return true.
269 /// </returns>
270 public bool StartingWorkItem()
271 {
272 _waitingOnQueueStopwatch.Stop();
273 _processingStopwatch.Start();
274
275 lock (this)
276 {
277 if (IsCanceled)
278 {
279 bool result = false;
280 if ((_workItemInfo.PostExecuteWorkItemCallback != null) &&
281 ((_workItemInfo.CallToPostExecute & CallToPostExecute.WhenWorkItemCanceled) == CallToPostExecute.WhenWorkItemCanceled))
282 {
283 result = true;
284 }
285
286 return result;
287 }
288
289 Debug.Assert(WorkItemState.InQueue == GetWorkItemState());
290
291 // No need for a lock yet, only after the state has changed to InProgress
292 _executingThread = Thread.CurrentThread;
293
294 SetWorkItemState(WorkItemState.InProgress);
295 }
296
297 return true;
298 }
299
300 /// <summary>
301 /// Execute the work item and the post execute
302 /// </summary>
303 public void Execute()
304 {
305 CallToPostExecute currentCallToPostExecute = 0;
306
307 // Execute the work item if we are in the correct state
308 switch (GetWorkItemState())
309 {
310 case WorkItemState.InProgress:
311 currentCallToPostExecute |= CallToPostExecute.WhenWorkItemNotCanceled;
312 ExecuteWorkItem();
313 break;
314 case WorkItemState.Canceled:
315 currentCallToPostExecute |= CallToPostExecute.WhenWorkItemCanceled;
316 break;
317 default:
318 Debug.Assert(false);
319 throw new NotSupportedException();
320 }
321
322 // Run the post execute as needed
323 if ((currentCallToPostExecute & _workItemInfo.CallToPostExecute) != 0)
324 {
325 PostExecute();
326 }
327
328 _processingStopwatch.Stop();
329 }
330
331 internal void FireWorkItemCompleted()
332 {
333 try
334 {
335 if (null != _workItemCompletedEvent)
336 {
337 _workItemCompletedEvent(this);
338 }
339 }
340 catch // Suppress exceptions
341 { }
342 }
343
344 internal void FireWorkItemStarted()
345 {
346 try
347 {
348 if (null != _workItemStartedEvent)
349 {
350 _workItemStartedEvent(this);
351 }
352 }
353 catch // Suppress exceptions
354 { }
355 }
356
357 /// <summary>
358 /// Execute the work item
359 /// </summary>
360 private void ExecuteWorkItem()
361 {
362
363#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
364 CallerThreadContext ctc = null;
365 if (null != _callerContext)
366 {
367 ctc = CallerThreadContext.Capture(_callerContext.CapturedCallContext, _callerContext.CapturedHttpContext);
368 CallerThreadContext.Apply(_callerContext);
369 }
370#endif
371
372 Exception exception = null;
373 object result = null;
374
375 try
376 {
377 try
378 {
379 result = _callback(_state);
380 }
381 catch (Exception e)
382 {
383 // Save the exception so we can rethrow it later
384 exception = e;
385 }
386
387 // Remove the value of the execution thread, so it will be impossible to cancel the work item,
388 // since it is already completed.
389 // Cancelling a work item that already completed may cause the abortion of the next work item!!!
390 Thread executionThread = Interlocked.CompareExchange(ref _executingThread, null, _executingThread);
391
392 if (null == executionThread)
393 {
394 // Oops! we are going to be aborted..., Wait here so we can catch the ThreadAbortException
395 Thread.Sleep(60 * 1000);
396
397 // If after 1 minute this thread was not aborted then let it continue working.
398 }
399 }
400 // We must treat the ThreadAbortException or else it will be stored in the exception variable
401 catch (ThreadAbortException tae)
402 {
403 tae.GetHashCode();
404 // Check if the work item was cancelled
405 // If we got a ThreadAbortException and the STP is not shutting down, it means the
406 // work items was cancelled.
407 if (!SmartThreadPool.CurrentThreadEntry.AssociatedSmartThreadPool.IsShuttingdown)
408 {
409#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
410 Thread.ResetAbort();
411#endif
412 }
413 }
414
415#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
416 if (null != _callerContext)
417 {
418 CallerThreadContext.Apply(ctc);
419 }
420#endif
421
422 if (!SmartThreadPool.IsWorkItemCanceled)
423 {
424 SetResult(result, exception);
425 }
426 }
427
428 /// <summary>
429 /// Runs the post execute callback
430 /// </summary>
431 private void PostExecute()
432 {
433 if (null != _workItemInfo.PostExecuteWorkItemCallback)
434 {
435 try
436 {
437 _workItemInfo.PostExecuteWorkItemCallback(_workItemResult);
438 }
439 catch (Exception e)
440 {
441 Debug.Assert(null != e);
442 }
443 }
444 }
445
446 /// <summary>
447 /// Set the result of the work item to return
448 /// </summary>
449 /// <param name="result">The result of the work item</param>
450 /// <param name="exception">The exception that was throw while the workitem executed, null
451 /// if there was no exception.</param>
452 internal void SetResult(object result, Exception exception)
453 {
454 _result = result;
455 _exception = exception;
456 SignalComplete(false);
457 }
458
459 /// <summary>
460 /// Returns the work item result
461 /// </summary>
462 /// <returns>The work item result</returns>
463 internal IWorkItemResult GetWorkItemResult()
464 {
465 return _workItemResult;
466 }
467
468 /// <summary>
469 /// Wait for all work items to complete
470 /// </summary>
471 /// <param name="waitableResults">Array of work item result objects</param>
472 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
473 /// <param name="exitContext">
474 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
475 /// </param>
476 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
477 /// <returns>
478 /// true when every work item in waitableResults has completed; otherwise false.
479 /// </returns>
480 internal static bool WaitAll(
481 IWaitableResult[] waitableResults,
482 int millisecondsTimeout,
483 bool exitContext,
484 WaitHandle cancelWaitHandle)
485 {
486 if (0 == waitableResults.Length)
487 {
488 return true;
489 }
490
491 bool success;
492 WaitHandle[] waitHandles = new WaitHandle[waitableResults.Length];
493 GetWaitHandles(waitableResults, waitHandles);
494
495 if ((null == cancelWaitHandle) && (waitHandles.Length <= 64))
496 {
497 success = STPEventWaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext);
498 }
499 else
500 {
501 success = true;
502 int millisecondsLeft = millisecondsTimeout;
503 Stopwatch stopwatch = Stopwatch.StartNew();
504
505 WaitHandle[] whs;
506 if (null != cancelWaitHandle)
507 {
508 whs = new WaitHandle[] { null, cancelWaitHandle };
509 }
510 else
511 {
512 whs = new WaitHandle[] { null };
513 }
514
515 bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout);
516 // Iterate over the wait handles and wait for each one to complete.
517 // We cannot use WaitHandle.WaitAll directly, because the cancelWaitHandle
518 // won't affect it.
519 // Each iteration we update the time left for the timeout.
520 for (int i = 0; i < waitableResults.Length; ++i)
521 {
522 // WaitAny don't work with negative numbers
523 if (!waitInfinitely && (millisecondsLeft < 0))
524 {
525 success = false;
526 break;
527 }
528
529 whs[0] = waitHandles[i];
530 int result = STPEventWaitHandle.WaitAny(whs, millisecondsLeft, exitContext);
531 if ((result > 0) || (STPEventWaitHandle.WaitTimeout == result))
532 {
533 success = false;
534 break;
535 }
536
537 if (!waitInfinitely)
538 {
539 // Update the time left to wait
540 millisecondsLeft = millisecondsTimeout - (int)stopwatch.ElapsedMilliseconds;
541 }
542 }
543 }
544 // Release the wait handles
545 ReleaseWaitHandles(waitableResults);
546
547 return success;
548 }
549
550 /// <summary>
551 /// Waits for any of the work items in the specified array to complete, cancel, or timeout
552 /// </summary>
553 /// <param name="waitableResults">Array of work item result objects</param>
554 /// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
555 /// <param name="exitContext">
556 /// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
557 /// </param>
558 /// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
559 /// <returns>
560 /// The array index of the work item result that satisfied the wait, or WaitTimeout if no work item result satisfied the wait and a time interval equivalent to millisecondsTimeout has passed or the work item has been canceled.
561 /// </returns>
562 internal static int WaitAny(
563 IWaitableResult[] waitableResults,
564 int millisecondsTimeout,
565 bool exitContext,
566 WaitHandle cancelWaitHandle)
567 {
568 WaitHandle[] waitHandles;
569
570 if (null != cancelWaitHandle)
571 {
572 waitHandles = new WaitHandle[waitableResults.Length + 1];
573 GetWaitHandles(waitableResults, waitHandles);
574 waitHandles[waitableResults.Length] = cancelWaitHandle;
575 }
576 else
577 {
578 waitHandles = new WaitHandle[waitableResults.Length];
579 GetWaitHandles(waitableResults, waitHandles);
580 }
581
582 int result = STPEventWaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);
583
584 // Treat cancel as timeout
585 if (null != cancelWaitHandle)
586 {
587 if (result == waitableResults.Length)
588 {
589 result = STPEventWaitHandle.WaitTimeout;
590 }
591 }
592
593 ReleaseWaitHandles(waitableResults);
594
595 return result;
596 }
597
598 /// <summary>
599 /// Fill an array of wait handles with the work items wait handles.
600 /// </summary>
601 /// <param name="waitableResults">An array of work item results</param>
602 /// <param name="waitHandles">An array of wait handles to fill</param>
603 private static void GetWaitHandles(
604 IWaitableResult[] waitableResults,
605 WaitHandle[] waitHandles)
606 {
607 for (int i = 0; i < waitableResults.Length; ++i)
608 {
609 WorkItemResult wir = waitableResults[i].GetWorkItemResult() as WorkItemResult;
610 Debug.Assert(null != wir, "All waitableResults must be WorkItemResult objects");
611
612 waitHandles[i] = wir.GetWorkItem().GetWaitHandle();
613 }
614 }
615
616 /// <summary>
617 /// Release the work items' wait handles
618 /// </summary>
619 /// <param name="waitableResults">An array of work item results</param>
620 private static void ReleaseWaitHandles(IWaitableResult[] waitableResults)
621 {
622 for (int i = 0; i < waitableResults.Length; ++i)
623 {
624 WorkItemResult wir = (WorkItemResult)waitableResults[i].GetWorkItemResult();
625
626 wir.GetWorkItem().ReleaseWaitHandle();
627 }
628 }
629
630 #endregion
631
632 #region Private Members
633
634 private WorkItemState GetWorkItemState()
635 {
636 lock (this)
637 {
638 if (WorkItemState.Completed == _workItemState)
639 {
640 return _workItemState;
641 }
642
643 long nowTicks = DateTime.UtcNow.Ticks;
644
645 if (WorkItemState.Canceled != _workItemState && nowTicks > _expirationTime)
646 {
647 _workItemState = WorkItemState.Canceled;
648 }
649
650 if (WorkItemState.InProgress == _workItemState)
651 {
652 return _workItemState;
653 }
654
655 if (CanceledSmartThreadPool.IsCanceled || CanceledWorkItemsGroup.IsCanceled)
656 {
657 return WorkItemState.Canceled;
658 }
659
660 return _workItemState;
661 }
662 }
663
664
665 /// <summary>
666 /// Sets the work item's state
667 /// </summary>
668 /// <param name="workItemState">The state to set the work item to</param>
669 private void SetWorkItemState(WorkItemState workItemState)
670 {
671 lock (this)
672 {
673 if (IsValidStatesTransition(_workItemState, workItemState))
674 {
675 _workItemState = workItemState;
676 }
677 }
678 }
679
680 /// <summary>
681 /// Signals that work item has been completed or canceled
682 /// </summary>
683 /// <param name="canceled">Indicates that the work item has been canceled</param>
684 private void SignalComplete(bool canceled)
685 {
686 SetWorkItemState(canceled ? WorkItemState.Canceled : WorkItemState.Completed);
687 lock (this)
688 {
689 // If someone is waiting then signal.
690 if (null != _workItemCompleted)
691 {
692 _workItemCompleted.Set();
693 }
694 }
695 }
696
697 internal void WorkItemIsQueued()
698 {
699 _waitingOnQueueStopwatch.Start();
700 }
701
702 #endregion
703
704 #region Members exposed by WorkItemResult
705
706 /// <summary>
707 /// Cancel the work item if it didn't start running yet.
708 /// </summary>
709 /// <returns>Returns true on success or false if the work item is in progress or already completed</returns>
710 private bool Cancel(bool abortExecution)
711 {
712#if (_WINDOWS_CE)
713 if(abortExecution)
714 {
715 throw new ArgumentOutOfRangeException("abortExecution", "WindowsCE doesn't support this feature");
716 }
717#endif
718 bool success = false;
719 bool signalComplete = false;
720
721 lock (this)
722 {
723 switch (GetWorkItemState())
724 {
725 case WorkItemState.Canceled:
726 //Debug.WriteLine("Work item already canceled");
727 if (abortExecution)
728 {
729 Thread executionThread = Interlocked.CompareExchange(ref _executingThread, null, _executingThread);
730 if (null != executionThread)
731 {
732 executionThread.Abort(); // "Cancel"
733 // No need to signalComplete, because we already cancelled this work item
734 // so it already signaled its completion.
735 //signalComplete = true;
736 }
737 }
738 success = true;
739 break;
740 case WorkItemState.Completed:
741 //Debug.WriteLine("Work item cannot be canceled");
742 break;
743 case WorkItemState.InProgress:
744 if (abortExecution)
745 {
746 Thread executionThread = Interlocked.CompareExchange(ref _executingThread, null, _executingThread);
747 if (null != executionThread)
748 {
749 executionThread.Abort(); // "Cancel"
750 success = true;
751 signalComplete = true;
752 }
753 }
754 else
755 {
756 // **************************
757 // Stock SmartThreadPool 2.2.3 sets these to true and relies on the thread to check the
758 // WorkItem cancellation status. However, OpenSimulator uses a different mechanism to notify
759 // scripts of co-operative termination and the abort code also relies on this method
760 // returning false in order to implement a small wait.
761 //
762 // Therefore, as was the case previously with STP, we will not signal successful cancellation
763 // here. It's possible that OpenSimulator code could be changed in the future to remove
764 // the need for this change.
765 // **************************
766 success = false;
767 signalComplete = false;
768 }
769 break;
770 case WorkItemState.InQueue:
771 // Signal to the wait for completion that the work
772 // item has been completed (canceled). There is no
773 // reason to wait for it to get out of the queue
774 signalComplete = true;
775 //Debug.WriteLine("Work item canceled");
776 success = true;
777 break;
778 }
779
780 if (signalComplete)
781 {
782 SignalComplete(true);
783 }
784 }
785 return success;
786 }
787
788 /// <summary>
789 /// Get the result of the work item.
790 /// If the work item didn't run yet then the caller waits for the result, timeout, or cancel.
791 /// In case of error the method throws and exception
792 /// </summary>
793 /// <returns>The result of the work item</returns>
794 private object GetResult(
795 int millisecondsTimeout,
796 bool exitContext,
797 WaitHandle cancelWaitHandle)
798 {
799 Exception e;
800 object result = GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
801 if (null != e)
802 {
803 throw new WorkItemResultException("The work item caused an excpetion, see the inner exception for details", e);
804 }
805 return result;
806 }
807
808 /// <summary>
809 /// Get the result of the work item.
810 /// If the work item didn't run yet then the caller waits for the result, timeout, or cancel.
811 /// In case of error the e argument is filled with the exception
812 /// </summary>
813 /// <returns>The result of the work item</returns>
814 private object GetResult(
815 int millisecondsTimeout,
816 bool exitContext,
817 WaitHandle cancelWaitHandle,
818 out Exception e)
819 {
820 e = null;
821
822 // Check for cancel
823 if (WorkItemState.Canceled == GetWorkItemState())
824 {
825 throw new WorkItemCancelException("Work item canceled");
826 }
827
828 // Check for completion
829 if (IsCompleted)
830 {
831 e = _exception;
832 return _result;
833 }
834
835 // If no cancelWaitHandle is provided
836 if (null == cancelWaitHandle)
837 {
838 WaitHandle wh = GetWaitHandle();
839
840 bool timeout = !STPEventWaitHandle.WaitOne(wh, millisecondsTimeout, exitContext);
841
842 ReleaseWaitHandle();
843
844 if (timeout)
845 {
846 throw new WorkItemTimeoutException("Work item timeout");
847 }
848 }
849 else
850 {
851 WaitHandle wh = GetWaitHandle();
852 int result = STPEventWaitHandle.WaitAny(new WaitHandle[] { wh, cancelWaitHandle });
853 ReleaseWaitHandle();
854
855 switch (result)
856 {
857 case 0:
858 // The work item signaled
859 // Note that the signal could be also as a result of canceling the
860 // work item (not the get result)
861 break;
862 case 1:
863 case STPEventWaitHandle.WaitTimeout:
864 throw new WorkItemTimeoutException("Work item timeout");
865 default:
866 Debug.Assert(false);
867 break;
868
869 }
870 }
871
872 // Check for cancel
873 if (WorkItemState.Canceled == GetWorkItemState())
874 {
875 throw new WorkItemCancelException("Work item canceled");
876 }
877
878 Debug.Assert(IsCompleted);
879
880 e = _exception;
881
882 // Return the result
883 return _result;
884 }
885
886 /// <summary>
887 /// A wait handle to wait for completion, cancel, or timeout
888 /// </summary>
889 private WaitHandle GetWaitHandle()
890 {
891 lock (this)
892 {
893 if (null == _workItemCompleted)
894 {
895 _workItemCompleted = EventWaitHandleFactory.CreateManualResetEvent(IsCompleted);
896 }
897 ++_workItemCompletedRefCount;
898 }
899 return _workItemCompleted;
900 }
901
902 private void ReleaseWaitHandle()
903 {
904 lock (this)
905 {
906 if (null != _workItemCompleted)
907 {
908 --_workItemCompletedRefCount;
909 if (0 == _workItemCompletedRefCount)
910 {
911 _workItemCompleted.Close();
912 _workItemCompleted = null;
913 }
914 }
915 }
916 }
917
918 /// <summary>
919 /// Returns true when the work item has completed or canceled
920 /// </summary>
921 private bool IsCompleted
922 {
923 get
924 {
925 lock (this)
926 {
927 WorkItemState workItemState = GetWorkItemState();
928 return ((workItemState == WorkItemState.Completed) ||
929 (workItemState == WorkItemState.Canceled));
930 }
931 }
932 }
933
934 /// <summary>
935 /// Returns true when the work item has canceled
936 /// </summary>
937 public bool IsCanceled
938 {
939 get
940 {
941 lock (this)
942 {
943 return (GetWorkItemState() == WorkItemState.Canceled);
944 }
945 }
946 }
947
948 #endregion
949
950 #region IHasWorkItemPriority Members
951
952 /// <summary>
953 /// Returns the priority of the work item
954 /// </summary>
955 public WorkItemPriority WorkItemPriority
956 {
957 get
958 {
959 return _workItemInfo.WorkItemPriority;
960 }
961 }
962
963 #endregion
964
965 internal event WorkItemStateCallback OnWorkItemStarted
966 {
967 add
968 {
969 _workItemStartedEvent += value;
970 }
971 remove
972 {
973 _workItemStartedEvent -= value;
974 }
975 }
976
977 internal event WorkItemStateCallback OnWorkItemCompleted
978 {
979 add
980 {
981 _workItemCompletedEvent += value;
982 }
983 remove
984 {
985 _workItemCompletedEvent -= value;
986 }
987 }
988
989 public void DisposeOfState()
990 {
991 if (_workItemInfo.DisposeOfStateObjects)
992 {
993 IDisposable disp = _state as IDisposable;
994 if (null != disp)
995 {
996 disp.Dispose();
997 _state = null;
998 }
999 }
1000 }
1001 }
1002}
diff --git a/ThirdParty/SmartThreadPool/WorkItemFactory.cs b/ThirdParty/SmartThreadPool/WorkItemFactory.cs
new file mode 100644
index 0000000..471eb20
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/WorkItemFactory.cs
@@ -0,0 +1,343 @@
1using System;
2
3namespace Amib.Threading.Internal
4{
5 #region WorkItemFactory class
6
7 public class WorkItemFactory
8 {
9 /// <summary>
10 /// Create a new work item
11 /// </summary>
12 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
13 /// <param name="wigStartInfo">Work item group start information</param>
14 /// <param name="callback">A callback to execute</param>
15 /// <returns>Returns a work item</returns>
16 public static WorkItem CreateWorkItem(
17 IWorkItemsGroup workItemsGroup,
18 WIGStartInfo wigStartInfo,
19 WorkItemCallback callback)
20 {
21 return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null);
22 }
23
24 /// <summary>
25 /// Create a new work item
26 /// </summary>
27 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
28 /// <param name="wigStartInfo">Work item group start information</param>
29 /// <param name="callback">A callback to execute</param>
30 /// <param name="workItemPriority">The priority of the work item</param>
31 /// <returns>Returns a work item</returns>
32 public static WorkItem CreateWorkItem(
33 IWorkItemsGroup workItemsGroup,
34 WIGStartInfo wigStartInfo,
35 WorkItemCallback callback,
36 WorkItemPriority workItemPriority)
37 {
38 return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null, workItemPriority);
39 }
40
41 /// <summary>
42 /// Create a new work item
43 /// </summary>
44 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
45 /// <param name="wigStartInfo">Work item group start information</param>
46 /// <param name="workItemInfo">Work item info</param>
47 /// <param name="callback">A callback to execute</param>
48 /// <returns>Returns a work item</returns>
49 public static WorkItem CreateWorkItem(
50 IWorkItemsGroup workItemsGroup,
51 WIGStartInfo wigStartInfo,
52 WorkItemInfo workItemInfo,
53 WorkItemCallback callback)
54 {
55 return CreateWorkItem(
56 workItemsGroup,
57 wigStartInfo,
58 workItemInfo,
59 callback,
60 null);
61 }
62
63 /// <summary>
64 /// Create a new work item
65 /// </summary>
66 /// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
67 /// <param name="wigStartInfo">Work item group start information</param>
68 /// <param name="callback">A callback to execute</param>
69 /// <param name="state">
70 /// The context object of the work item. Used for passing arguments to the work item.
71 /// </param>
72 /// <returns>Returns a work item</returns>
73 public static WorkItem CreateWorkItem(
74 IWorkItemsGroup workItemsGroup,
75 WIGStartInfo wigStartInfo,
76 WorkItemCallback callback,
77 object state)
78 {
79 ValidateCallback(callback);
80
81 WorkItemInfo workItemInfo = new WorkItemInfo();
82 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
83 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
84 workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
85 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
86 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
87 workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
88
89 WorkItem workItem = new WorkItem(
90 workItemsGroup,
91 workItemInfo,
92 callback,
93 state);
94 return workItem;
95 }
96
97 /// <summary>
98 /// Create a new work item
99 /// </summary>
100 /// <param name="workItemsGroup">The work items group</param>
101 /// <param name="wigStartInfo">Work item group start information</param>
102 /// <param name="callback">A callback to execute</param>
103 /// <param name="state">
104 /// The context object of the work item. Used for passing arguments to the work item.
105 /// </param>
106 /// <param name="workItemPriority">The work item priority</param>
107 /// <returns>Returns a work item</returns>
108 public static WorkItem CreateWorkItem(
109 IWorkItemsGroup workItemsGroup,
110 WIGStartInfo wigStartInfo,
111 WorkItemCallback callback,
112 object state,
113 WorkItemPriority workItemPriority)
114 {
115 ValidateCallback(callback);
116
117 WorkItemInfo workItemInfo = new WorkItemInfo();
118 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
119 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
120 workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
121 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
122 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
123 workItemInfo.WorkItemPriority = workItemPriority;
124
125 WorkItem workItem = new WorkItem(
126 workItemsGroup,
127 workItemInfo,
128 callback,
129 state);
130
131 return workItem;
132 }
133
134 /// <summary>
135 /// Create a new work item
136 /// </summary>
137 /// <param name="workItemsGroup">The work items group</param>
138 /// <param name="wigStartInfo">Work item group start information</param>
139 /// <param name="workItemInfo">Work item information</param>
140 /// <param name="callback">A callback to execute</param>
141 /// <param name="state">
142 /// The context object of the work item. Used for passing arguments to the work item.
143 /// </param>
144 /// <returns>Returns a work item</returns>
145 public static WorkItem CreateWorkItem(
146 IWorkItemsGroup workItemsGroup,
147 WIGStartInfo wigStartInfo,
148 WorkItemInfo workItemInfo,
149 WorkItemCallback callback,
150 object state)
151 {
152 ValidateCallback(callback);
153 ValidateCallback(workItemInfo.PostExecuteWorkItemCallback);
154
155 WorkItem workItem = new WorkItem(
156 workItemsGroup,
157 new WorkItemInfo(workItemInfo),
158 callback,
159 state);
160
161 return workItem;
162 }
163
164 /// <summary>
165 /// Create a new work item
166 /// </summary>
167 /// <param name="workItemsGroup">The work items group</param>
168 /// <param name="wigStartInfo">Work item group start information</param>
169 /// <param name="callback">A callback to execute</param>
170 /// <param name="state">
171 /// The context object of the work item. Used for passing arguments to the work item.
172 /// </param>
173 /// <param name="postExecuteWorkItemCallback">
174 /// A delegate to call after the callback completion
175 /// </param>
176 /// <returns>Returns a work item</returns>
177 public static WorkItem CreateWorkItem(
178 IWorkItemsGroup workItemsGroup,
179 WIGStartInfo wigStartInfo,
180 WorkItemCallback callback,
181 object state,
182 PostExecuteWorkItemCallback postExecuteWorkItemCallback)
183 {
184 ValidateCallback(callback);
185 ValidateCallback(postExecuteWorkItemCallback);
186
187 WorkItemInfo workItemInfo = new WorkItemInfo();
188 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
189 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
190 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
191 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
192 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
193 workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
194
195 WorkItem workItem = new WorkItem(
196 workItemsGroup,
197 workItemInfo,
198 callback,
199 state);
200
201 return workItem;
202 }
203
204 /// <summary>
205 /// Create a new work item
206 /// </summary>
207 /// <param name="workItemsGroup">The work items group</param>
208 /// <param name="wigStartInfo">Work item group start information</param>
209 /// <param name="callback">A callback to execute</param>
210 /// <param name="state">
211 /// The context object of the work item. Used for passing arguments to the work item.
212 /// </param>
213 /// <param name="postExecuteWorkItemCallback">
214 /// A delegate to call after the callback completion
215 /// </param>
216 /// <param name="workItemPriority">The work item priority</param>
217 /// <returns>Returns a work item</returns>
218 public static WorkItem CreateWorkItem(
219 IWorkItemsGroup workItemsGroup,
220 WIGStartInfo wigStartInfo,
221 WorkItemCallback callback,
222 object state,
223 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
224 WorkItemPriority workItemPriority)
225 {
226 ValidateCallback(callback);
227 ValidateCallback(postExecuteWorkItemCallback);
228
229 WorkItemInfo workItemInfo = new WorkItemInfo();
230 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
231 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
232 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
233 workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute;
234 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
235 workItemInfo.WorkItemPriority = workItemPriority;
236
237 WorkItem workItem = new WorkItem(
238 workItemsGroup,
239 workItemInfo,
240 callback,
241 state);
242
243 return workItem;
244 }
245
246 /// <summary>
247 /// Create a new work item
248 /// </summary>
249 /// <param name="workItemsGroup">The work items group</param>
250 /// <param name="wigStartInfo">Work item group start information</param>
251 /// <param name="callback">A callback to execute</param>
252 /// <param name="state">
253 /// The context object of the work item. Used for passing arguments to the work item.
254 /// </param>
255 /// <param name="postExecuteWorkItemCallback">
256 /// A delegate to call after the callback completion
257 /// </param>
258 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
259 /// <returns>Returns a work item</returns>
260 public static WorkItem CreateWorkItem(
261 IWorkItemsGroup workItemsGroup,
262 WIGStartInfo wigStartInfo,
263 WorkItemCallback callback,
264 object state,
265 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
266 CallToPostExecute callToPostExecute)
267 {
268 ValidateCallback(callback);
269 ValidateCallback(postExecuteWorkItemCallback);
270
271 WorkItemInfo workItemInfo = new WorkItemInfo();
272 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
273 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
274 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
275 workItemInfo.CallToPostExecute = callToPostExecute;
276 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
277 workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority;
278
279 WorkItem workItem = new WorkItem(
280 workItemsGroup,
281 workItemInfo,
282 callback,
283 state);
284
285 return workItem;
286 }
287
288 /// <summary>
289 /// Create a new work item
290 /// </summary>
291 /// <param name="workItemsGroup">The work items group</param>
292 /// <param name="wigStartInfo">Work item group start information</param>
293 /// <param name="callback">A callback to execute</param>
294 /// <param name="state">
295 /// The context object of the work item. Used for passing arguments to the work item.
296 /// </param>
297 /// <param name="postExecuteWorkItemCallback">
298 /// A delegate to call after the callback completion
299 /// </param>
300 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
301 /// <param name="workItemPriority">The work item priority</param>
302 /// <returns>Returns a work item</returns>
303 public static WorkItem CreateWorkItem(
304 IWorkItemsGroup workItemsGroup,
305 WIGStartInfo wigStartInfo,
306 WorkItemCallback callback,
307 object state,
308 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
309 CallToPostExecute callToPostExecute,
310 WorkItemPriority workItemPriority)
311 {
312
313 ValidateCallback(callback);
314 ValidateCallback(postExecuteWorkItemCallback);
315
316 WorkItemInfo workItemInfo = new WorkItemInfo();
317 workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext;
318 workItemInfo.UseCallerHttpContext = wigStartInfo.UseCallerHttpContext;
319 workItemInfo.PostExecuteWorkItemCallback = postExecuteWorkItemCallback;
320 workItemInfo.CallToPostExecute = callToPostExecute;
321 workItemInfo.WorkItemPriority = workItemPriority;
322 workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
323
324 WorkItem workItem = new WorkItem(
325 workItemsGroup,
326 workItemInfo,
327 callback,
328 state);
329
330 return workItem;
331 }
332
333 private static void ValidateCallback(Delegate callback)
334 {
335 if (callback != null && callback.GetInvocationList().Length > 1)
336 {
337 throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
338 }
339 }
340 }
341
342 #endregion
343}
diff --git a/ThirdParty/SmartThreadPool/WorkItemInfo.cs b/ThirdParty/SmartThreadPool/WorkItemInfo.cs
new file mode 100644
index 0000000..5be82a2
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/WorkItemInfo.cs
@@ -0,0 +1,69 @@
1namespace Amib.Threading
2{
3 #region WorkItemInfo class
4
5 /// <summary>
6 /// Summary description for WorkItemInfo.
7 /// </summary>
8 public class WorkItemInfo
9 {
10 public WorkItemInfo()
11 {
12 UseCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
13 UseCallerHttpContext = SmartThreadPool.DefaultUseCallerHttpContext;
14 DisposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
15 CallToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
16 PostExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
17 WorkItemPriority = SmartThreadPool.DefaultWorkItemPriority;
18 }
19
20 public WorkItemInfo(WorkItemInfo workItemInfo)
21 {
22 UseCallerCallContext = workItemInfo.UseCallerCallContext;
23 UseCallerHttpContext = workItemInfo.UseCallerHttpContext;
24 DisposeOfStateObjects = workItemInfo.DisposeOfStateObjects;
25 CallToPostExecute = workItemInfo.CallToPostExecute;
26 PostExecuteWorkItemCallback = workItemInfo.PostExecuteWorkItemCallback;
27 WorkItemPriority = workItemInfo.WorkItemPriority;
28 Timeout = workItemInfo.Timeout;
29 }
30
31 /// <summary>
32 /// Get/Set if to use the caller's security context
33 /// </summary>
34 public bool UseCallerCallContext { get; set; }
35
36 /// <summary>
37 /// Get/Set if to use the caller's HTTP context
38 /// </summary>
39 public bool UseCallerHttpContext { get; set; }
40
41 /// <summary>
42 /// Get/Set if to dispose of the state object of a work item
43 /// </summary>
44 public bool DisposeOfStateObjects { get; set; }
45
46 /// <summary>
47 /// Get/Set the run the post execute options
48 /// </summary>
49 public CallToPostExecute CallToPostExecute { get; set; }
50
51 /// <summary>
52 /// Get/Set the post execute callback
53 /// </summary>
54 public PostExecuteWorkItemCallback PostExecuteWorkItemCallback { get; set; }
55
56 /// <summary>
57 /// Get/Set the work item's priority
58 /// </summary>
59 public WorkItemPriority WorkItemPriority { get; set; }
60
61 /// <summary>
62 /// Get/Set the work item's timout in milliseconds.
63 /// This is a passive timout. When the timout expires the work item won't be actively aborted!
64 /// </summary>
65 public long Timeout { get; set; }
66 }
67
68 #endregion
69}
diff --git a/ThirdParty/SmartThreadPool/WorkItemResultTWrapper.cs b/ThirdParty/SmartThreadPool/WorkItemResultTWrapper.cs
new file mode 100644
index 0000000..d1eff95
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/WorkItemResultTWrapper.cs
@@ -0,0 +1,128 @@
1using System;
2using System.Threading;
3
4namespace Amib.Threading.Internal
5{
6 #region WorkItemResultTWrapper class
7
8 internal class WorkItemResultTWrapper<TResult> : IWorkItemResult<TResult>, IInternalWaitableResult
9 {
10 private readonly IWorkItemResult _workItemResult;
11
12 public WorkItemResultTWrapper(IWorkItemResult workItemResult)
13 {
14 _workItemResult = workItemResult;
15 }
16
17 #region IWorkItemResult<TResult> Members
18
19 public TResult GetResult()
20 {
21 return (TResult)_workItemResult.GetResult();
22 }
23
24 public TResult GetResult(int millisecondsTimeout, bool exitContext)
25 {
26 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext);
27 }
28
29 public TResult GetResult(TimeSpan timeout, bool exitContext)
30 {
31 return (TResult)_workItemResult.GetResult(timeout, exitContext);
32 }
33
34 public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
35 {
36 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
37 }
38
39 public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
40 {
41 return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle);
42 }
43
44 public TResult GetResult(out Exception e)
45 {
46 return (TResult)_workItemResult.GetResult(out e);
47 }
48
49 public TResult GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
50 {
51 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, out e);
52 }
53
54 public TResult GetResult(TimeSpan timeout, bool exitContext, out Exception e)
55 {
56 return (TResult)_workItemResult.GetResult(timeout, exitContext, out e);
57 }
58
59 public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
60 {
61 return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
62 }
63
64 public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
65 {
66 return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle, out e);
67 }
68
69 public bool IsCompleted
70 {
71 get { return _workItemResult.IsCompleted; }
72 }
73
74 public bool IsCanceled
75 {
76 get { return _workItemResult.IsCanceled; }
77 }
78
79 public object State
80 {
81 get { return _workItemResult.State; }
82 }
83
84 public bool Cancel()
85 {
86 return _workItemResult.Cancel();
87 }
88
89 public bool Cancel(bool abortExecution)
90 {
91 return _workItemResult.Cancel(abortExecution);
92 }
93
94 public WorkItemPriority WorkItemPriority
95 {
96 get { return _workItemResult.WorkItemPriority; }
97 }
98
99 public TResult Result
100 {
101 get { return (TResult)_workItemResult.Result; }
102 }
103
104 public object Exception
105 {
106 get { return (TResult)_workItemResult.Exception; }
107 }
108
109 #region IInternalWorkItemResult Members
110
111 public IWorkItemResult GetWorkItemResult()
112 {
113 return _workItemResult.GetWorkItemResult();
114 }
115
116 public IWorkItemResult<TRes> GetWorkItemResultT<TRes>()
117 {
118 return (IWorkItemResult<TRes>)this;
119 }
120
121 #endregion
122
123 #endregion
124 }
125
126 #endregion
127
128}
diff --git a/ThirdParty/SmartThreadPool/WorkItemsGroup.cs b/ThirdParty/SmartThreadPool/WorkItemsGroup.cs
new file mode 100644
index 0000000..d429bc6
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/WorkItemsGroup.cs
@@ -0,0 +1,361 @@
1using System;
2using System.Threading;
3using System.Runtime.CompilerServices;
4using System.Diagnostics;
5
6namespace Amib.Threading.Internal
7{
8
9 #region WorkItemsGroup class
10
11 /// <summary>
12 /// Summary description for WorkItemsGroup.
13 /// </summary>
14 public class WorkItemsGroup : WorkItemsGroupBase
15 {
16 #region Private members
17
18 private readonly object _lock = new object();
19
20 /// <summary>
21 /// A reference to the SmartThreadPool instance that created this
22 /// WorkItemsGroup.
23 /// </summary>
24 private readonly SmartThreadPool _stp;
25
26 /// <summary>
27 /// The OnIdle event
28 /// </summary>
29 private event WorkItemsGroupIdleHandler _onIdle;
30
31 /// <summary>
32 /// A flag to indicate if the Work Items Group is now suspended.
33 /// </summary>
34 private bool _isSuspended;
35
36 /// <summary>
37 /// Defines how many work items of this WorkItemsGroup can run at once.
38 /// </summary>
39 private int _concurrency;
40
41 /// <summary>
42 /// Priority queue to hold work items before they are passed
43 /// to the SmartThreadPool.
44 /// </summary>
45 private readonly PriorityQueue _workItemsQueue;
46
47 /// <summary>
48 /// Indicate how many work items are waiting in the SmartThreadPool
49 /// queue.
50 /// This value is used to apply the concurrency.
51 /// </summary>
52 private int _workItemsInStpQueue;
53
54 /// <summary>
55 /// Indicate how many work items are currently running in the SmartThreadPool.
56 /// This value is used with the Cancel, to calculate if we can send new
57 /// work items to the STP.
58 /// </summary>
59 private int _workItemsExecutingInStp = 0;
60
61 /// <summary>
62 /// WorkItemsGroup start information
63 /// </summary>
64 private readonly WIGStartInfo _workItemsGroupStartInfo;
65
66 /// <summary>
67 /// Signaled when all of the WorkItemsGroup's work item completed.
68 /// </summary>
69 //private readonly ManualResetEvent _isIdleWaitHandle = new ManualResetEvent(true);
70 private readonly ManualResetEvent _isIdleWaitHandle = EventWaitHandleFactory.CreateManualResetEvent(true);
71
72 /// <summary>
73 /// A common object for all the work items that this work items group
74 /// generate so we can mark them to cancel in O(1)
75 /// </summary>
76 private CanceledWorkItemsGroup _canceledWorkItemsGroup = new CanceledWorkItemsGroup();
77
78 #endregion
79
80 #region Construction
81
82 public WorkItemsGroup(
83 SmartThreadPool stp,
84 int concurrency,
85 WIGStartInfo wigStartInfo)
86 {
87 if (concurrency <= 0)
88 {
89 throw new ArgumentOutOfRangeException(
90 "concurrency",
91#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
92 concurrency,
93#endif
94 "concurrency must be greater than zero");
95 }
96 _stp = stp;
97 _concurrency = concurrency;
98 _workItemsGroupStartInfo = new WIGStartInfo(wigStartInfo).AsReadOnly();
99 _workItemsQueue = new PriorityQueue();
100 Name = "WorkItemsGroup";
101
102 // The _workItemsInStpQueue gets the number of currently executing work items,
103 // because once a work item is executing, it cannot be cancelled.
104 _workItemsInStpQueue = _workItemsExecutingInStp;
105
106 _isSuspended = _workItemsGroupStartInfo.StartSuspended;
107 }
108
109 #endregion
110
111 #region WorkItemsGroupBase Overrides
112
113 public override int Concurrency
114 {
115 get { return _concurrency; }
116 set
117 {
118 Debug.Assert(value > 0);
119
120 int diff = value - _concurrency;
121 _concurrency = value;
122 if (diff > 0)
123 {
124 EnqueueToSTPNextNWorkItem(diff);
125 }
126 }
127 }
128
129 public override int WaitingCallbacks
130 {
131 get { return _workItemsQueue.Count; }
132 }
133
134 public override object[] GetStates()
135 {
136 lock (_lock)
137 {
138 object[] states = new object[_workItemsQueue.Count];
139 int i = 0;
140 foreach (WorkItem workItem in _workItemsQueue)
141 {
142 states[i] = workItem.GetWorkItemResult().State;
143 ++i;
144 }
145 return states;
146 }
147 }
148
149 /// <summary>
150 /// WorkItemsGroup start information
151 /// </summary>
152 public override WIGStartInfo WIGStartInfo
153 {
154 get { return _workItemsGroupStartInfo; }
155 }
156
157 /// <summary>
158 /// Start the Work Items Group if it was started suspended
159 /// </summary>
160 public override void Start()
161 {
162 // If the Work Items Group already started then quit
163 if (!_isSuspended)
164 {
165 return;
166 }
167 _isSuspended = false;
168
169 EnqueueToSTPNextNWorkItem(Math.Min(_workItemsQueue.Count, _concurrency));
170 }
171
172 public override void Cancel(bool abortExecution)
173 {
174 lock (_lock)
175 {
176 _canceledWorkItemsGroup.IsCanceled = true;
177 _workItemsQueue.Clear();
178 _workItemsInStpQueue = 0;
179 _canceledWorkItemsGroup = new CanceledWorkItemsGroup();
180 }
181
182 if (abortExecution)
183 {
184 _stp.CancelAbortWorkItemsGroup(this);
185 }
186 }
187
188 /// <summary>
189 /// Wait for the thread pool to be idle
190 /// </summary>
191 public override bool WaitForIdle(int millisecondsTimeout)
192 {
193 SmartThreadPool.ValidateWorkItemsGroupWaitForIdle(this);
194 return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
195 }
196
197 public override event WorkItemsGroupIdleHandler OnIdle
198 {
199 add { _onIdle += value; }
200 remove { _onIdle -= value; }
201 }
202
203 #endregion
204
205 #region Private methods
206
207 private void RegisterToWorkItemCompletion(IWorkItemResult wir)
208 {
209 IInternalWorkItemResult iwir = (IInternalWorkItemResult)wir;
210 iwir.OnWorkItemStarted += OnWorkItemStartedCallback;
211 iwir.OnWorkItemCompleted += OnWorkItemCompletedCallback;
212 }
213
214 public void OnSTPIsStarting()
215 {
216 if (_isSuspended)
217 {
218 return;
219 }
220
221 EnqueueToSTPNextNWorkItem(_concurrency);
222 }
223
224 public void EnqueueToSTPNextNWorkItem(int count)
225 {
226 for (int i = 0; i < count; ++i)
227 {
228 EnqueueToSTPNextWorkItem(null, false);
229 }
230 }
231
232 private object FireOnIdle(object state)
233 {
234 FireOnIdleImpl(_onIdle);
235 return null;
236 }
237
238 [MethodImpl(MethodImplOptions.NoInlining)]
239 private void FireOnIdleImpl(WorkItemsGroupIdleHandler onIdle)
240 {
241 if(null == onIdle)
242 {
243 return;
244 }
245
246 Delegate[] delegates = onIdle.GetInvocationList();
247 foreach(WorkItemsGroupIdleHandler eh in delegates)
248 {
249 try
250 {
251 eh(this);
252 }
253 catch { } // Suppress exceptions
254 }
255 }
256
257 private void OnWorkItemStartedCallback(WorkItem workItem)
258 {
259 lock(_lock)
260 {
261 ++_workItemsExecutingInStp;
262 }
263 }
264
265 private void OnWorkItemCompletedCallback(WorkItem workItem)
266 {
267 EnqueueToSTPNextWorkItem(null, true);
268 }
269
270 internal override void Enqueue(WorkItem workItem)
271 {
272 EnqueueToSTPNextWorkItem(workItem);
273 }
274
275 private void EnqueueToSTPNextWorkItem(WorkItem workItem)
276 {
277 EnqueueToSTPNextWorkItem(workItem, false);
278 }
279
280 private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue)
281 {
282 lock(_lock)
283 {
284 // Got here from OnWorkItemCompletedCallback()
285 if (decrementWorkItemsInStpQueue)
286 {
287 --_workItemsInStpQueue;
288
289 if(_workItemsInStpQueue < 0)
290 {
291 _workItemsInStpQueue = 0;
292 }
293
294 --_workItemsExecutingInStp;
295
296 if(_workItemsExecutingInStp < 0)
297 {
298 _workItemsExecutingInStp = 0;
299 }
300 }
301
302 // If the work item is not null then enqueue it
303 if (null != workItem)
304 {
305 workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup;
306
307 RegisterToWorkItemCompletion(workItem.GetWorkItemResult());
308 _workItemsQueue.Enqueue(workItem);
309 //_stp.IncrementWorkItemsCount();
310
311 if ((1 == _workItemsQueue.Count) &&
312 (0 == _workItemsInStpQueue))
313 {
314 _stp.RegisterWorkItemsGroup(this);
315 IsIdle = false;
316 _isIdleWaitHandle.Reset();
317 }
318 }
319
320 // If the work items queue of the group is empty than quit
321 if (0 == _workItemsQueue.Count)
322 {
323 if (0 == _workItemsInStpQueue)
324 {
325 _stp.UnregisterWorkItemsGroup(this);
326 IsIdle = true;
327 _isIdleWaitHandle.Set();
328 if (decrementWorkItemsInStpQueue && _onIdle != null && _onIdle.GetInvocationList().Length > 0)
329 {
330 _stp.QueueWorkItem(new WorkItemCallback(FireOnIdle));
331 }
332 }
333 return;
334 }
335
336 if (!_isSuspended)
337 {
338 if (_workItemsInStpQueue < _concurrency)
339 {
340 WorkItem nextWorkItem = _workItemsQueue.Dequeue() as WorkItem;
341 try
342 {
343 _stp.Enqueue(nextWorkItem);
344 }
345 catch (ObjectDisposedException e)
346 {
347 e.GetHashCode();
348 // The STP has been shutdown
349 }
350
351 ++_workItemsInStpQueue;
352 }
353 }
354 }
355 }
356
357 #endregion
358 }
359
360 #endregion
361}
diff --git a/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs b/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs
new file mode 100644
index 0000000..3a5dcc6
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs
@@ -0,0 +1,471 @@
1using System;
2using System.Threading;
3
4namespace Amib.Threading.Internal
5{
6 public abstract class WorkItemsGroupBase : IWorkItemsGroup
7 {
8 #region Private Fields
9
10 /// <summary>
11 /// Contains the name of this instance of SmartThreadPool.
12 /// Can be changed by the user.
13 /// </summary>
14 private string _name = "WorkItemsGroupBase";
15
16 public WorkItemsGroupBase()
17 {
18 IsIdle = true;
19 }
20
21 #endregion
22
23 #region IWorkItemsGroup Members
24
25 #region Public Methods
26
27 /// <summary>
28 /// Get/Set the name of the SmartThreadPool/WorkItemsGroup instance
29 /// </summary>
30 public string Name
31 {
32 get { return _name; }
33 set { _name = value; }
34 }
35
36 #endregion
37
38 #region Abstract Methods
39
40 public abstract int Concurrency { get; set; }
41 public abstract int WaitingCallbacks { get; }
42 public abstract object[] GetStates();
43 public abstract WIGStartInfo WIGStartInfo { get; }
44 public abstract void Start();
45 public abstract void Cancel(bool abortExecution);
46 public abstract bool WaitForIdle(int millisecondsTimeout);
47 public abstract event WorkItemsGroupIdleHandler OnIdle;
48
49 internal abstract void Enqueue(WorkItem workItem);
50 internal virtual void PreQueueWorkItem() { }
51
52 #endregion
53
54 #region Common Base Methods
55
56 /// <summary>
57 /// Cancel all the work items.
58 /// Same as Cancel(false)
59 /// </summary>
60 public virtual void Cancel()
61 {
62 Cancel(false);
63 }
64
65 /// <summary>
66 /// Wait for the SmartThreadPool/WorkItemsGroup to be idle
67 /// </summary>
68 public void WaitForIdle()
69 {
70 WaitForIdle(Timeout.Infinite);
71 }
72
73 /// <summary>
74 /// Wait for the SmartThreadPool/WorkItemsGroup to be idle
75 /// </summary>
76 public bool WaitForIdle(TimeSpan timeout)
77 {
78 return WaitForIdle((int)timeout.TotalMilliseconds);
79 }
80
81 /// <summary>
82 /// IsIdle is true when there are no work items running or queued.
83 /// </summary>
84 public bool IsIdle { get; protected set; }
85
86 #endregion
87
88 #region QueueWorkItem
89
90 /// <summary>
91 /// Queue a work item
92 /// </summary>
93 /// <param name="callback">A callback to execute</param>
94 /// <returns>Returns a work item result</returns>
95 public IWorkItemResult QueueWorkItem(WorkItemCallback callback)
96 {
97 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback);
98 Enqueue(workItem);
99 return workItem.GetWorkItemResult();
100 }
101
102 /// <summary>
103 /// Queue a work item
104 /// </summary>
105 /// <param name="callback">A callback to execute</param>
106 /// <param name="workItemPriority">The priority of the work item</param>
107 /// <returns>Returns a work item result</returns>
108 public IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority)
109 {
110 PreQueueWorkItem();
111 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, workItemPriority);
112 Enqueue(workItem);
113 return workItem.GetWorkItemResult();
114 }
115
116 /// <summary>
117 /// Queue a work item
118 /// </summary>
119 /// <param name="workItemInfo">Work item info</param>
120 /// <param name="callback">A callback to execute</param>
121 /// <returns>Returns a work item result</returns>
122 public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback)
123 {
124 PreQueueWorkItem();
125 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback);
126 Enqueue(workItem);
127 return workItem.GetWorkItemResult();
128 }
129
130 /// <summary>
131 /// Queue a work item
132 /// </summary>
133 /// <param name="callback">A callback to execute</param>
134 /// <param name="state">
135 /// The context object of the work item. Used for passing arguments to the work item.
136 /// </param>
137 /// <returns>Returns a work item result</returns>
138 public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state)
139 {
140 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
141 Enqueue(workItem);
142 return workItem.GetWorkItemResult();
143 }
144
145 /// <summary>
146 /// Queue a work item
147 /// </summary>
148 /// <param name="callback">A callback to execute</param>
149 /// <param name="state">
150 /// The context object of the work item. Used for passing arguments to the work item.
151 /// </param>
152 /// <param name="workItemPriority">The work item priority</param>
153 /// <returns>Returns a work item result</returns>
154 public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority)
155 {
156 PreQueueWorkItem();
157 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, workItemPriority);
158 Enqueue(workItem);
159 return workItem.GetWorkItemResult();
160 }
161
162 /// <summary>
163 /// Queue a work item
164 /// </summary>
165 /// <param name="workItemInfo">Work item information</param>
166 /// <param name="callback">A callback to execute</param>
167 /// <param name="state">
168 /// The context object of the work item. Used for passing arguments to the work item.
169 /// </param>
170 /// <returns>Returns a work item result</returns>
171 public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
172 {
173 PreQueueWorkItem();
174 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
175 Enqueue(workItem);
176 return workItem.GetWorkItemResult();
177 }
178
179 /// <summary>
180 /// Queue a work item
181 /// </summary>
182 /// <param name="callback">A callback to execute</param>
183 /// <param name="state">
184 /// The context object of the work item. Used for passing arguments to the work item.
185 /// </param>
186 /// <param name="postExecuteWorkItemCallback">
187 /// A delegate to call after the callback completion
188 /// </param>
189 /// <returns>Returns a work item result</returns>
190 public IWorkItemResult QueueWorkItem(
191 WorkItemCallback callback,
192 object state,
193 PostExecuteWorkItemCallback postExecuteWorkItemCallback)
194 {
195 PreQueueWorkItem();
196 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback);
197 Enqueue(workItem);
198 return workItem.GetWorkItemResult();
199 }
200
201 /// <summary>
202 /// Queue a work item
203 /// </summary>
204 /// <param name="callback">A callback to execute</param>
205 /// <param name="state">
206 /// The context object of the work item. Used for passing arguments to the work item.
207 /// </param>
208 /// <param name="postExecuteWorkItemCallback">
209 /// A delegate to call after the callback completion
210 /// </param>
211 /// <param name="workItemPriority">The work item priority</param>
212 /// <returns>Returns a work item result</returns>
213 public IWorkItemResult QueueWorkItem(
214 WorkItemCallback callback,
215 object state,
216 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
217 WorkItemPriority workItemPriority)
218 {
219 PreQueueWorkItem();
220 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, workItemPriority);
221 Enqueue(workItem);
222 return workItem.GetWorkItemResult();
223 }
224
225 /// <summary>
226 /// Queue a work item
227 /// </summary>
228 /// <param name="callback">A callback to execute</param>
229 /// <param name="state">
230 /// The context object of the work item. Used for passing arguments to the work item.
231 /// </param>
232 /// <param name="postExecuteWorkItemCallback">
233 /// A delegate to call after the callback completion
234 /// </param>
235 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
236 /// <returns>Returns a work item result</returns>
237 public IWorkItemResult QueueWorkItem(
238 WorkItemCallback callback,
239 object state,
240 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
241 CallToPostExecute callToPostExecute)
242 {
243 PreQueueWorkItem();
244 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute);
245 Enqueue(workItem);
246 return workItem.GetWorkItemResult();
247 }
248
249 /// <summary>
250 /// Queue a work item
251 /// </summary>
252 /// <param name="callback">A callback to execute</param>
253 /// <param name="state">
254 /// The context object of the work item. Used for passing arguments to the work item.
255 /// </param>
256 /// <param name="postExecuteWorkItemCallback">
257 /// A delegate to call after the callback completion
258 /// </param>
259 /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
260 /// <param name="workItemPriority">The work item priority</param>
261 /// <returns>Returns a work item result</returns>
262 public IWorkItemResult QueueWorkItem(
263 WorkItemCallback callback,
264 object state,
265 PostExecuteWorkItemCallback postExecuteWorkItemCallback,
266 CallToPostExecute callToPostExecute,
267 WorkItemPriority workItemPriority)
268 {
269 PreQueueWorkItem();
270 WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute, workItemPriority);
271 Enqueue(workItem);
272 return workItem.GetWorkItemResult();
273 }
274
275 #endregion
276
277 #region QueueWorkItem(Action<...>)
278
279 public IWorkItemResult QueueWorkItem(Action action)
280 {
281 return QueueWorkItem (action, SmartThreadPool.DefaultWorkItemPriority);
282 }
283
284 public IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority)
285 {
286 PreQueueWorkItem ();
287 WorkItem workItem = WorkItemFactory.CreateWorkItem (
288 this,
289 WIGStartInfo,
290 delegate
291 {
292 action.Invoke ();
293 return null;
294 }, priority);
295 Enqueue (workItem);
296 return workItem.GetWorkItemResult ();
297 }
298
299 public IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg)
300 {
301 return QueueWorkItem<T> (action, arg, SmartThreadPool.DefaultWorkItemPriority);
302 }
303
304 public IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority)
305 {
306 PreQueueWorkItem ();
307 WorkItem workItem = WorkItemFactory.CreateWorkItem (
308 this,
309 WIGStartInfo,
310 state =>
311 {
312 action.Invoke (arg);
313 return null;
314 },
315 WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null, priority);
316 Enqueue (workItem);
317 return workItem.GetWorkItemResult ();
318 }
319
320 public IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
321 {
322 return QueueWorkItem<T1, T2> (action, arg1, arg2, SmartThreadPool.DefaultWorkItemPriority);
323 }
324
325 public IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority)
326 {
327 PreQueueWorkItem ();
328 WorkItem workItem = WorkItemFactory.CreateWorkItem (
329 this,
330 WIGStartInfo,
331 state =>
332 {
333 action.Invoke (arg1, arg2);
334 return null;
335 },
336 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null, priority);
337 Enqueue (workItem);
338 return workItem.GetWorkItemResult ();
339 }
340
341 public IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
342 {
343 return QueueWorkItem<T1, T2, T3> (action, arg1, arg2, arg3, SmartThreadPool.DefaultWorkItemPriority);
344 ;
345 }
346
347 public IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority)
348 {
349 PreQueueWorkItem ();
350 WorkItem workItem = WorkItemFactory.CreateWorkItem (
351 this,
352 WIGStartInfo,
353 state =>
354 {
355 action.Invoke (arg1, arg2, arg3);
356 return null;
357 },
358 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null, priority);
359 Enqueue (workItem);
360 return workItem.GetWorkItemResult ();
361 }
362
363 public IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(
364 Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
365 {
366 return QueueWorkItem<T1, T2, T3, T4> (action, arg1, arg2, arg3, arg4,
367 SmartThreadPool.DefaultWorkItemPriority);
368 }
369
370 public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (
371 Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority)
372 {
373 PreQueueWorkItem ();
374 WorkItem workItem = WorkItemFactory.CreateWorkItem (
375 this,
376 WIGStartInfo,
377 state =>
378 {
379 action.Invoke (arg1, arg2, arg3, arg4);
380 return null;
381 },
382 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null, priority);
383 Enqueue (workItem);
384 return workItem.GetWorkItemResult ();
385 }
386
387 #endregion
388
389 #region QueueWorkItem(Func<...>)
390
391 public IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func)
392 {
393 PreQueueWorkItem();
394 WorkItem workItem = WorkItemFactory.CreateWorkItem(
395 this,
396 WIGStartInfo,
397 state =>
398 {
399 return func.Invoke();
400 });
401 Enqueue(workItem);
402 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
403 }
404
405 public IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg)
406 {
407 PreQueueWorkItem();
408 WorkItem workItem = WorkItemFactory.CreateWorkItem(
409 this,
410 WIGStartInfo,
411 state =>
412 {
413 return func.Invoke(arg);
414 },
415 WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null);
416 Enqueue(workItem);
417 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
418 }
419
420 public IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2)
421 {
422 PreQueueWorkItem();
423 WorkItem workItem = WorkItemFactory.CreateWorkItem(
424 this,
425 WIGStartInfo,
426 state =>
427 {
428 return func.Invoke(arg1, arg2);
429 },
430 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null);
431 Enqueue(workItem);
432 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
433 }
434
435 public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(
436 Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3)
437 {
438 PreQueueWorkItem();
439 WorkItem workItem = WorkItemFactory.CreateWorkItem(
440 this,
441 WIGStartInfo,
442 state =>
443 {
444 return func.Invoke(arg1, arg2, arg3);
445 },
446 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null);
447 Enqueue(workItem);
448 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
449 }
450
451 public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(
452 Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
453 {
454 PreQueueWorkItem();
455 WorkItem workItem = WorkItemFactory.CreateWorkItem(
456 this,
457 WIGStartInfo,
458 state =>
459 {
460 return func.Invoke(arg1, arg2, arg3, arg4);
461 },
462 WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null);
463 Enqueue(workItem);
464 return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
465 }
466
467 #endregion
468
469 #endregion
470 }
471} \ No newline at end of file
diff --git a/ThirdParty/SmartThreadPool/WorkItemsQueue.cs b/ThirdParty/SmartThreadPool/WorkItemsQueue.cs
new file mode 100644
index 0000000..21403a0
--- /dev/null
+++ b/ThirdParty/SmartThreadPool/WorkItemsQueue.cs
@@ -0,0 +1,646 @@
1using System;
2using System.Collections.Generic;
3using System.Threading;
4
5namespace Amib.Threading.Internal
6{
7 #region WorkItemsQueue class
8
9 /// <summary>
10 /// WorkItemsQueue class.
11 /// </summary>
12 public class WorkItemsQueue : IDisposable
13 {
14 #region Member variables
15
16 /// <summary>
17 /// Waiters queue (implemented as stack).
18 /// </summary>
19 private readonly WaiterEntry _headWaiterEntry = new WaiterEntry();
20
21 /// <summary>
22 /// Waiters count
23 /// </summary>
24 private int _waitersCount = 0;
25
26 /// <summary>
27 /// Work items queue
28 /// </summary>
29 private readonly PriorityQueue _workItems = new PriorityQueue();
30
31 /// <summary>
32 /// Indicate that work items are allowed to be queued
33 /// </summary>
34 private bool _isWorkItemsQueueActive = true;
35
36
37#if (WINDOWS_PHONE)
38 private static readonly Dictionary<int, WaiterEntry> _waiterEntries = new Dictionary<int, WaiterEntry>();
39#elif (_WINDOWS_CE)
40 private static LocalDataStoreSlot _waiterEntrySlot = Thread.AllocateDataSlot();
41#else
42
43 [ThreadStatic]
44 private static WaiterEntry _waiterEntry;
45#endif
46
47
48 /// <summary>
49 /// Each thread in the thread pool keeps its own waiter entry.
50 /// </summary>
51 private static WaiterEntry CurrentWaiterEntry
52 {
53#if (WINDOWS_PHONE)
54 get
55 {
56 lock (_waiterEntries)
57 {
58 WaiterEntry waiterEntry;
59 if (_waiterEntries.TryGetValue(Thread.CurrentThread.ManagedThreadId, out waiterEntry))
60 {
61 return waiterEntry;
62 }
63 }
64 return null;
65 }
66 set
67 {
68 lock (_waiterEntries)
69 {
70 _waiterEntries[Thread.CurrentThread.ManagedThreadId] = value;
71 }
72 }
73#elif (_WINDOWS_CE)
74 get
75 {
76 return Thread.GetData(_waiterEntrySlot) as WaiterEntry;
77 }
78 set
79 {
80 Thread.SetData(_waiterEntrySlot, value);
81 }
82#else
83 get
84 {
85 return _waiterEntry;
86 }
87 set
88 {
89 _waiterEntry = value;
90 }
91#endif
92 }
93
94 /// <summary>
95 /// A flag that indicates if the WorkItemsQueue has been disposed.
96 /// </summary>
97 private bool _isDisposed = false;
98
99 #endregion
100
101 #region Public properties
102
103 /// <summary>
104 /// Returns the current number of work items in the queue
105 /// </summary>
106 public int Count
107 {
108 get
109 {
110 return _workItems.Count;
111 }
112 }
113
114 /// <summary>
115 /// Returns the current number of waiters
116 /// </summary>
117 public int WaitersCount
118 {
119 get
120 {
121 return _waitersCount;
122 }
123 }
124
125
126 #endregion
127
128 #region Public methods
129
130 /// <summary>
131 /// Enqueue a work item to the queue.
132 /// </summary>
133 public bool EnqueueWorkItem(WorkItem workItem)
134 {
135 // A work item cannot be null, since null is used in the
136 // WaitForWorkItem() method to indicate timeout or cancel
137 if (null == workItem)
138 {
139 throw new ArgumentNullException("workItem" , "workItem cannot be null");
140 }
141
142 bool enqueue = true;
143
144 // First check if there is a waiter waiting for work item. During
145 // the check, timed out waiters are ignored. If there is no
146 // waiter then the work item is queued.
147 lock(this)
148 {
149 ValidateNotDisposed();
150
151 if (!_isWorkItemsQueueActive)
152 {
153 return false;
154 }
155
156 while(_waitersCount > 0)
157 {
158 // Dequeue a waiter.
159 WaiterEntry waiterEntry = PopWaiter();
160
161 // Signal the waiter. On success break the loop
162 if (waiterEntry.Signal(workItem))
163 {
164 enqueue = false;
165 break;
166 }
167 }
168
169 if (enqueue)
170 {
171 // Enqueue the work item
172 _workItems.Enqueue(workItem);
173 }
174 }
175 return true;
176 }
177
178
179 /// <summary>
180 /// Waits for a work item or exits on timeout or cancel
181 /// </summary>
182 /// <param name="millisecondsTimeout">Timeout in milliseconds</param>
183 /// <param name="cancelEvent">Cancel wait handle</param>
184 /// <returns>Returns true if the resource was granted</returns>
185 public WorkItem DequeueWorkItem(
186 int millisecondsTimeout,
187 WaitHandle cancelEvent)
188 {
189 // This method cause the caller to wait for a work item.
190 // If there is at least one waiting work item then the
191 // method returns immidiately with it.
192 //
193 // If there are no waiting work items then the caller
194 // is queued between other waiters for a work item to arrive.
195 //
196 // If a work item didn't come within millisecondsTimeout or
197 // the user canceled the wait by signaling the cancelEvent
198 // then the method returns null to indicate that the caller
199 // didn't get a work item.
200
201 WaiterEntry waiterEntry;
202 WorkItem workItem = null;
203 lock (this)
204 {
205 ValidateNotDisposed();
206
207 // If there are waiting work items then take one and return.
208 if (_workItems.Count > 0)
209 {
210 workItem = _workItems.Dequeue() as WorkItem;
211 return workItem;
212 }
213
214 // No waiting work items ...
215
216 // Get the waiter entry for the waiters queue
217 waiterEntry = GetThreadWaiterEntry();
218
219 // Put the waiter with the other waiters
220 PushWaiter(waiterEntry);
221 }
222
223 // Prepare array of wait handle for the WaitHandle.WaitAny()
224 WaitHandle [] waitHandles = new WaitHandle[] {
225 waiterEntry.WaitHandle,
226 cancelEvent };
227
228 // Wait for an available resource, cancel event, or timeout.
229
230 // During the wait we are supposes to exit the synchronization
231 // domain. (Placing true as the third argument of the WaitAny())
232 // It just doesn't work, I don't know why, so I have two lock(this)
233 // statments instead of one.
234
235 int index = STPEventWaitHandle.WaitAny(
236 waitHandles,
237 millisecondsTimeout,
238 true);
239
240 lock(this)
241 {
242 // success is true if it got a work item.
243 bool success = (0 == index);
244
245 // The timeout variable is used only for readability.
246 // (We treat cancel as timeout)
247 bool timeout = !success;
248
249 // On timeout update the waiterEntry that it is timed out
250 if (timeout)
251 {
252 // The Timeout() fails if the waiter has already been signaled
253 timeout = waiterEntry.Timeout();
254
255 // On timeout remove the waiter from the queue.
256 // Note that the complexity is O(1).
257 if(timeout)
258 {
259 RemoveWaiter(waiterEntry, false);
260 }
261
262 // Again readability
263 success = !timeout;
264 }
265
266 // On success return the work item
267 if (success)
268 {
269 workItem = waiterEntry.WorkItem;
270
271 if (null == workItem)
272 {
273 workItem = _workItems.Dequeue() as WorkItem;
274 }
275 }
276 }
277 // On failure return null.
278 return workItem;
279 }
280
281 /// <summary>
282 /// Cleanup the work items queue, hence no more work
283 /// items are allowed to be queue
284 /// </summary>
285 private void Cleanup()
286 {
287 lock(this)
288 {
289 // Deactivate only once
290 if (!_isWorkItemsQueueActive)
291 {
292 return;
293 }
294
295 // Don't queue more work items
296 _isWorkItemsQueueActive = false;
297
298 foreach(WorkItem workItem in _workItems)
299 {
300 workItem.DisposeOfState();
301 }
302
303 // Clear the work items that are already queued
304 _workItems.Clear();
305
306 // Note:
307 // I don't iterate over the queue and dispose of work items's states,
308 // since if a work item has a state object that is still in use in the
309 // application then I must not dispose it.
310
311 // Tell the waiters that they were timed out.
312 // It won't signal them to exit, but to ignore their
313 // next work item.
314 while(_waitersCount > 0)
315 {
316 WaiterEntry waiterEntry = PopWaiter();
317 waiterEntry.Timeout();
318 }
319 }
320 }
321
322 public object[] GetStates()
323 {
324 lock (this)
325 {
326 object[] states = new object[_workItems.Count];
327 int i = 0;
328 foreach (WorkItem workItem in _workItems)
329 {
330 states[i] = workItem.GetWorkItemResult().State;
331 ++i;
332 }
333 return states;
334 }
335 }
336
337 #endregion
338
339 #region Private methods
340
341 /// <summary>
342 /// Returns the WaiterEntry of the current thread
343 /// </summary>
344 /// <returns></returns>
345 /// In order to avoid creation and destuction of WaiterEntry
346 /// objects each thread has its own WaiterEntry object.
347 private static WaiterEntry GetThreadWaiterEntry()
348 {
349 if (null == CurrentWaiterEntry)
350 {
351 CurrentWaiterEntry = new WaiterEntry();
352 }
353 CurrentWaiterEntry.Reset();
354 return CurrentWaiterEntry;
355 }
356
357 #region Waiters stack methods
358
359 /// <summary>
360 /// Push a new waiter into the waiter's stack
361 /// </summary>
362 /// <param name="newWaiterEntry">A waiter to put in the stack</param>
363 public void PushWaiter(WaiterEntry newWaiterEntry)
364 {
365 // Remove the waiter if it is already in the stack and
366 // update waiter's count as needed
367 RemoveWaiter(newWaiterEntry, false);
368
369 // If the stack is empty then newWaiterEntry is the new head of the stack
370 if (null == _headWaiterEntry._nextWaiterEntry)
371 {
372 _headWaiterEntry._nextWaiterEntry = newWaiterEntry;
373 newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
374
375 }
376 // If the stack is not empty then put newWaiterEntry as the new head
377 // of the stack.
378 else
379 {
380 // Save the old first waiter entry
381 WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
382
383 // Update the links
384 _headWaiterEntry._nextWaiterEntry = newWaiterEntry;
385 newWaiterEntry._nextWaiterEntry = oldFirstWaiterEntry;
386 newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
387 oldFirstWaiterEntry._prevWaiterEntry = newWaiterEntry;
388 }
389
390 // Increment the number of waiters
391 ++_waitersCount;
392 }
393
394 /// <summary>
395 /// Pop a waiter from the waiter's stack
396 /// </summary>
397 /// <returns>Returns the first waiter in the stack</returns>
398 private WaiterEntry PopWaiter()
399 {
400 // Store the current stack head
401 WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
402
403 // Store the new stack head
404 WaiterEntry newHeadWaiterEntry = oldFirstWaiterEntry._nextWaiterEntry;
405
406 // Update the old stack head list links and decrement the number
407 // waiters.
408 RemoveWaiter(oldFirstWaiterEntry, true);
409
410 // Update the new stack head
411 _headWaiterEntry._nextWaiterEntry = newHeadWaiterEntry;
412 if (null != newHeadWaiterEntry)
413 {
414 newHeadWaiterEntry._prevWaiterEntry = _headWaiterEntry;
415 }
416
417 // Return the old stack head
418 return oldFirstWaiterEntry;
419 }
420
421 /// <summary>
422 /// Remove a waiter from the stack
423 /// </summary>
424 /// <param name="waiterEntry">A waiter entry to remove</param>
425 /// <param name="popDecrement">If true the waiter count is always decremented</param>
426 private void RemoveWaiter(WaiterEntry waiterEntry, bool popDecrement)
427 {
428 // Store the prev entry in the list
429 WaiterEntry prevWaiterEntry = waiterEntry._prevWaiterEntry;
430
431 // Store the next entry in the list
432 WaiterEntry nextWaiterEntry = waiterEntry._nextWaiterEntry;
433
434 // A flag to indicate if we need to decrement the waiters count.
435 // If we got here from PopWaiter then we must decrement.
436 // If we got here from PushWaiter then we decrement only if
437 // the waiter was already in the stack.
438 bool decrementCounter = popDecrement;
439
440 // Null the waiter's entry links
441 waiterEntry._prevWaiterEntry = null;
442 waiterEntry._nextWaiterEntry = null;
443
444 // If the waiter entry had a prev link then update it.
445 // It also means that the waiter is already in the list and we
446 // need to decrement the waiters count.
447 if (null != prevWaiterEntry)
448 {
449 prevWaiterEntry._nextWaiterEntry = nextWaiterEntry;
450 decrementCounter = true;
451 }
452
453 // If the waiter entry had a next link then update it.
454 // It also means that the waiter is already in the list and we
455 // need to decrement the waiters count.
456 if (null != nextWaiterEntry)
457 {
458 nextWaiterEntry._prevWaiterEntry = prevWaiterEntry;
459 decrementCounter = true;
460 }
461
462 // Decrement the waiters count if needed
463 if (decrementCounter)
464 {
465 --_waitersCount;
466 }
467 }
468
469 #endregion
470
471 #endregion
472
473 #region WaiterEntry class
474
475 // A waiter entry in the _waiters queue.
476 public sealed class WaiterEntry : IDisposable
477 {
478 #region Member variables
479
480 /// <summary>
481 /// Event to signal the waiter that it got the work item.
482 /// </summary>
483 //private AutoResetEvent _waitHandle = new AutoResetEvent(false);
484 private AutoResetEvent _waitHandle = EventWaitHandleFactory.CreateAutoResetEvent();
485
486 /// <summary>
487 /// Flag to know if this waiter already quited from the queue
488 /// because of a timeout.
489 /// </summary>
490 private bool _isTimedout = false;
491
492 /// <summary>
493 /// Flag to know if the waiter was signaled and got a work item.
494 /// </summary>
495 private bool _isSignaled = false;
496
497 /// <summary>
498 /// A work item that passed directly to the waiter withou going
499 /// through the queue
500 /// </summary>
501 private WorkItem _workItem = null;
502
503 private bool _isDisposed = false;
504
505 // Linked list members
506 internal WaiterEntry _nextWaiterEntry = null;
507 internal WaiterEntry _prevWaiterEntry = null;
508
509 #endregion
510
511 #region Construction
512
513 public WaiterEntry()
514 {
515 Reset();
516 }
517
518 #endregion
519
520 #region Public methods
521
522 public WaitHandle WaitHandle
523 {
524 get { return _waitHandle; }
525 }
526
527 public WorkItem WorkItem
528 {
529 get
530 {
531 return _workItem;
532 }
533 }
534
535 /// <summary>
536 /// Signal the waiter that it got a work item.
537 /// </summary>
538 /// <returns>Return true on success</returns>
539 /// The method fails if Timeout() preceded its call
540 public bool Signal(WorkItem workItem)
541 {
542 lock(this)
543 {
544 if (!_isTimedout)
545 {
546 _workItem = workItem;
547 _isSignaled = true;
548 _waitHandle.Set();
549 return true;
550 }
551 }
552 return false;
553 }
554
555 /// <summary>
556 /// Mark the wait entry that it has been timed out
557 /// </summary>
558 /// <returns>Return true on success</returns>
559 /// The method fails if Signal() preceded its call
560 public bool Timeout()
561 {
562 lock(this)
563 {
564 // Time out can happen only if the waiter wasn't marked as
565 // signaled
566 if (!_isSignaled)
567 {
568 // We don't remove the waiter from the queue, the DequeueWorkItem
569 // method skips _waiters that were timed out.
570 _isTimedout = true;
571 return true;
572 }
573 }
574 return false;
575 }
576
577 /// <summary>
578 /// Reset the wait entry so it can be used again
579 /// </summary>
580 public void Reset()
581 {
582 _workItem = null;
583 _isTimedout = false;
584 _isSignaled = false;
585 _waitHandle.Reset();
586 }
587
588 /// <summary>
589 /// Free resources
590 /// </summary>
591 public void Close()
592 {
593 if (null != _waitHandle)
594 {
595 _waitHandle.Close();
596 _waitHandle = null;
597 }
598 }
599
600 #endregion
601
602 #region IDisposable Members
603
604 public void Dispose()
605 {
606 lock (this)
607 {
608 if (!_isDisposed)
609 {
610 Close();
611 }
612 _isDisposed = true;
613 }
614 }
615
616 #endregion
617 }
618
619 #endregion
620
621 #region IDisposable Members
622
623 public void Dispose()
624 {
625 if (!_isDisposed)
626 {
627 Cleanup();
628 _headWaiterEntry.Close();
629 }
630 _isDisposed = true;
631 }
632
633 private void ValidateNotDisposed()
634 {
635 if(_isDisposed)
636 {
637 throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
638 }
639 }
640
641 #endregion
642 }
643
644 #endregion
645}
646
diff --git a/ThirdPartyLicenses/Aurora-Sim.txt b/ThirdPartyLicenses/Aurora-Sim.txt
new file mode 100644
index 0000000..162d552
--- /dev/null
+++ b/ThirdPartyLicenses/Aurora-Sim.txt
@@ -0,0 +1,26 @@
1/*
2 * Copyright (c) Contributors, http://aurora-sim.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the Aurora-Sim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
diff --git a/ThirdPartyLicenses/Axiom.txt b/ThirdPartyLicenses/Axiom.txt
new file mode 100644
index 0000000..fe97db2
--- /dev/null
+++ b/ThirdPartyLicenses/Axiom.txt
@@ -0,0 +1,141 @@
1GNU LESSER GENERAL PUBLIC LICENSE
2Version 2.1, February 1999
3
4
5Copyright (C) 1991, 1999 Free Software Foundation, Inc.
659 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7Everyone is permitted to copy and distribute verbatim copies
8of this license document, but changing it is not allowed.
9
10[This is the first released version of the Lesser GPL. It also counts
11 as the successor of the GNU Library Public License, version 2, hence
12 the version number 2.1.]
13
14Preamble
15The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.
16
17This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.
18
19When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.
20
21To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.
22
23For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
24
25We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.
26
27To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.
28
29Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.
30
31Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.
32
33When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.
34
35We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
36
37For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.
38
39In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
40
41Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.
42
43The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
44
45
46TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
470. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".
48
49A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.
50
51The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)
52
53"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.
54
55Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.
56
571. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.
58
59You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
60
612. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
62
63
64a) The modified work must itself be a software library.
65b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
66c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
67d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.
68(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
69
70These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
71
72Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.
73
74In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
75
763. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.
77
78Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.
79
80This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
81
824. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.
83
84If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.
85
865. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.
87
88However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.
89
90When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.
91
92If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)
93
94Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.
95
966. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.
97
98You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
99
100
101a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
102b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
103c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
104d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
105e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
106For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
107
108It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.
109
1107. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:
111
112
113a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
114b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
1158. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
116
1179. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.
118
11910. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.
120
12111. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.
122
123If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.
124
125It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
126
127This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
128
12912. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
130
13113. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
132
133Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.
134
13514. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
136
137NO WARRANTY
138
13915. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
140
14116. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. \ No newline at end of file
diff --git a/ThirdPartyLicenses/BclExtras.txt b/ThirdPartyLicenses/BclExtras.txt
new file mode 100644
index 0000000..a8a0292
--- /dev/null
+++ b/ThirdPartyLicenses/BclExtras.txt
@@ -0,0 +1,60 @@
1MICROSOFT PUBLIC LICENSE (Ms-PL)
2
3This license governs use of the accompanying software. If you use the software,
4you accept this license. If you do not accept the license, do not use the
5software.
6
71. Definitions
8
9The terms "reproduce," "reproduction," "derivative works," and "distribution"
10have the same meaning here as under U.S. copyright law.
11
12A "contribution" is the original software, or any additions or changes to the
13software.
14
15A "contributor" is any person that distributes its contribution under this
16license.
17
18"Licensed patents" are a contributor's patent claims that read directly on its
19contribution.
20
212. Grant of Rights
22
23(A) Copyright Grant- Subject to the terms of this license, including the license
24conditions and limitations in section 3, each contributor grants you a
25non-exclusive, worldwide, royalty-free copyright license to reproduce its
26contribution, prepare derivative works of its contribution, and distribute its
27contribution or any derivative works that you create.
28
29(B) Patent Grant- Subject to the terms of this license, including the license
30conditions and limitations in section 3, each contributor grants you a
31non-exclusive, worldwide, royalty-free license under its licensed patents to
32make, have made, use, sell, offer for sale, import, and/or otherwise dispose of
33its contribution in the software or derivative works of the contribution in the
34software.
35
363. Conditions and Limitations
37
38(A) No Trademark License- This license does not grant you rights to use any
39contributors' name, logo, or trademarks.
40
41(B) If you bring a patent claim against any contributor over patents that you
42claim are infringed by the software, your patent license from such contributor
43to the software ends automatically.
44
45(C) If you distribute any portion of the software, you must retain all
46copyright, patent, trademark, and attribution notices that are present in the
47software.
48
49(D) If you distribute any portion of the software in source code form, you may
50do so only under this license by including a complete copy of this license with
51your distribution. If you distribute any portion of the software in compiled or
52object code form, you may only do so under a license that complies with this
53license.
54
55(E) The software is licensed "as-is." You bear the risk of using it. The
56contributors give no express warranties, guarantees or conditions. You may have
57additional consumer rights under your local laws which this license cannot
58change. To the extent permitted under your local laws, the contributors exclude
59the implied warranties of merchantability, fitness for a particular purpose and
60non-infringement.
diff --git a/ThirdPartyLicenses/Bullet for Xna (ModifiedBulletX).txt b/ThirdPartyLicenses/Bullet for Xna (ModifiedBulletX).txt
new file mode 100644
index 0000000..a8ed924
--- /dev/null
+++ b/ThirdPartyLicenses/Bullet for Xna (ModifiedBulletX).txt
@@ -0,0 +1,19 @@
1 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
2 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19 \ No newline at end of file
diff --git a/ThirdPartyLicenses/Bullet-XNA.txt b/ThirdPartyLicenses/Bullet-XNA.txt
new file mode 100644
index 0000000..5d8899b
--- /dev/null
+++ b/ThirdPartyLicenses/Bullet-XNA.txt
@@ -0,0 +1,23 @@
1/*
2 * C# / XNA port of Bullet (c) 2011 Mark Neale <xexuxjy@hotmail.com>
3 * http://code.google.com/p/bullet-xna/
4 *
5 * Bullet Continuous Collision Detection and Physics Library
6 * Copyright (c) 2003-2008 Erwin Coumans http://www.bulletphysics.com/
7 *
8 * This software is provided 'as-is', without any express or implied warranty.
9 * In no event will the authors be held liable for any damages arising from
10 * the use of this software.
11 *
12 * Permission is granted to anyone to use this software for any purpose,
13 * including commercial applications, and to alter it and redistribute it
14 * freely, subject to the following restrictions:
15 *
16 * 1. The origin of this software must not be misrepresented; you must not
17 * claim that you wrote the original software. If you use this software
18 * in a product, an acknowledgment in the product documentation would be
19 * appreciated but is not required.
20 * 2. Altered source versions must be plainly marked as such, and must not be
21 * misrepresented as being the original software.
22 * 3. This notice may not be removed or altered from any source distribution.
23 */ \ No newline at end of file
diff --git a/ThirdPartyLicenses/BulletLicense.txt b/ThirdPartyLicenses/BulletLicense.txt
new file mode 100644
index 0000000..c3ec68c
--- /dev/null
+++ b/ThirdPartyLicenses/BulletLicense.txt
@@ -0,0 +1,17 @@
1/*
2Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
3
4This software is provided 'as-is', without any express or implied warranty.
5In no event will the authors be held liable for any damages arising from the use of this software.
6Permission is granted to anyone to use this software for any purpose,
7including commercial applications, and to alter it and redistribute it freely,
8subject to the following restrictions:
9
101. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
112. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
123. This notice may not be removed or altered from any source distribution.
13*/
14
15
16Free for commercial use, but please mail bullet@erwincoumans.com to report projects, and join the forum at
17www.continuousphysics.com/Bullet/phpBB2
diff --git a/ThirdPartyLicenses/C# Webserver.txt b/ThirdPartyLicenses/C# Webserver.txt
new file mode 100644
index 0000000..b996891
--- /dev/null
+++ b/ThirdPartyLicenses/C# Webserver.txt
@@ -0,0 +1,71 @@
1Files: HttpServer_OpenSim.dll
2
3Apache License
4Version 2.0, January 2004
5http://www.apache.org/licenses/
6
7TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
8
91. Definitions.
10
11"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
12
13"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
14
15"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
16
17"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
18
19"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
20
21"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
22
23"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
24
25"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
26
27"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
28
29"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
30
312. Grant of Copyright License.
32
33Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
34
353. Grant of Patent License.
36
37Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
38
394. Redistribution.
40
41You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
42
431. You must give any other recipients of the Work or Derivative Works a copy of this License; and
44
452. You must cause any modified files to carry prominent notices stating that You changed the files; and
46
473. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
48
494. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
50
51You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
52
535. Submission of Contributions.
54
55Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
56
576. Trademarks.
58
59This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
60
617. Disclaimer of Warranty.
62
63Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
64
658. Limitation of Liability.
66
67In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
68
699. Accepting Warranty or Additional Liability.
70
71While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. \ No newline at end of file
diff --git a/ThirdPartyLicenses/C5.txt b/ThirdPartyLicenses/C5.txt
new file mode 100644
index 0000000..4c3a049
--- /dev/null
+++ b/ThirdPartyLicenses/C5.txt
@@ -0,0 +1,19 @@
1Copyright (c) 2003-2008 Niels Kokholm and Peter Sestoft.
2
3Permission is hereby granted, free of charge, to any person obtaining a copy
4of this software and associated documentation files (the "Software"), to deal
5in the Software without restriction, including without limitation the rights
6to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7copies of the Software, and to permit persons to whom the Software is
8furnished to do so, subject to the following conditions:
9
10The above copyright notice and this permission notice shall be included in
11all copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19SOFTWARE \ No newline at end of file
diff --git a/ThirdPartyLicenses/CSCompilerTools.txt b/ThirdPartyLicenses/CSCompilerTools.txt
new file mode 100644
index 0000000..c2567bd
--- /dev/null
+++ b/ThirdPartyLicenses/CSCompilerTools.txt
@@ -0,0 +1,12 @@
1The LSL compiler is generated with "Compiler tools in C#" version 4.7[1] by Dr. Malcolm Crowe[2]. The code is used with permission by the author:
2
3There is no problem with using the code in any way you like, as long as
4somewhere you say that that is what you have done (in the source for
5example).
6And of course we disclaim all responsibility for any resulting
7damage...
8Best wishes
9Malcolm Crowe
10
11[1] http://cis.paisley.ac.uk/crow-ci0/CSTools47.zip
12[2] http://cis.paisley.ac.uk/crow-ci0/
diff --git a/ThirdPartyLicenses/CSJ2K.txt b/ThirdPartyLicenses/CSJ2K.txt
new file mode 100644
index 0000000..3032548
--- /dev/null
+++ b/ThirdPartyLicenses/CSJ2K.txt
@@ -0,0 +1,28 @@
1Copyright (c) 1999/2000 JJ2000 Partners.
2
3This software module was originally developed by Raphaël Grosbois and
4Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
5Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
6Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
7Centre France S.A) in the course of development of the JPEG2000
8standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
9software module is an implementation of a part of the JPEG 2000
10Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
11Systems AB and Canon Research Centre France S.A (collectively JJ2000
12Partners) agree not to assert against ISO/IEC and users of the JPEG
132000 Standard (Users) any of their rights under the copyright, not
14including other intellectual property rights, for this software module
15with respect to the usage by ISO/IEC and Users of this software module
16or modifications thereof for use in hardware or software products
17claiming conformance to the JPEG 2000 Standard. Those intending to use
18this software module in hardware or software products are advised that
19their use may infringe existing patents. The original developers of
20this software module, JJ2000 Partners and ISO/IEC assume no liability
21for use of this software module or modifications thereof. No license
22or right to this software module is granted for non JPEG 2000 Standard
23conforming products. JJ2000 Partners have full right to use this
24software module for his/her own purpose, assign or donate this
25software module to any third party and to inhibit third parties from
26using this software module for non JPEG 2000 Standard conforming
27products. This copyright notice must be included in all copies or
28derivative works of this software module.
diff --git a/ThirdPartyLicenses/CircularBuffer.txt b/ThirdPartyLicenses/CircularBuffer.txt
new file mode 100644
index 0000000..09c37d9
--- /dev/null
+++ b/ThirdPartyLicenses/CircularBuffer.txt
@@ -0,0 +1,16 @@
1Copyright (c) 2012, Alex Regueiro
2All rights reserved.
3Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
4following conditions are met:
5
6Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
8in the documentation and/or other materials provided with the distribution.
9
10THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
11BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
12IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
13OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
14OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
15OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
16POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/ThirdPartyLicenses/ConvexDecompositionDotNet.txt b/ThirdPartyLicenses/ConvexDecompositionDotNet.txt
new file mode 100644
index 0000000..714ae89
--- /dev/null
+++ b/ThirdPartyLicenses/ConvexDecompositionDotNet.txt
@@ -0,0 +1,28 @@
1ConvexDecompositionDotNet
2-------------------------
3
4The MIT License
5
6Copyright (c) 2010 Intel Corporation.
7All rights reserved.
8
9Based on the convexdecomposition library from
10<http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files (the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in
20all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28THE SOFTWARE.
diff --git a/ThirdPartyLicenses/DefaultTerrain.txt b/ThirdPartyLicenses/DefaultTerrain.txt
new file mode 100644
index 0000000..112beff
--- /dev/null
+++ b/ThirdPartyLicenses/DefaultTerrain.txt
@@ -0,0 +1,23 @@
1 COPYRIGHT AND PERMISSION NOTICE
2
3Second Life(TM) Viewer Artwork. Copyright (C) 2008 Linden Research, Inc.
4
5Linden Research, Inc. ("Linden Lab") licenses the Second Life viewer
6artwork and other works in the files distributed with this Notice under
7the Creative Commons Attribution-Share Alike 3.0 License, available at
8http://creativecommons.org/licenses/by-sa/3.0/legalcode. [^] For the license
9summary, see http://creativecommons.org/licenses/by-sa/3.0/.
10
11Notwithstanding the foregoing, all of Linden Lab's trademarks, including
12but not limited to the Second Life brand name and Second Life Eye-in-Hand
13logo, are subject to our trademark policy at
14http://secondlife.com/corporate/trademark/.
15
16If you distribute any copies or adaptations of the Second Life viewer
17artwork or any other works in these files, you must include this Notice
18and clearly identify any changes made to the original works. Include
19this Notice and information where copyright notices are usually included,
20for example, after your own copyright notice acknowledging your use of
21the Second Life viewer artwork, in a text file distributed with your
22program, in your application's About window, or on a credits page for
23your work.
diff --git a/ThirdPartyLicenses/DotNetOpenid.txt b/ThirdPartyLicenses/DotNetOpenid.txt
new file mode 100644
index 0000000..6833494
--- /dev/null
+++ b/ThirdPartyLicenses/DotNetOpenid.txt
@@ -0,0 +1,10 @@
1Copyright (c) 2008, Andrew Arnott, Scott Hanselman, Jason Alexander, et. al
2All rights reserved.
3
4Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
6 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 * Neither the name of the DotNetOpenId nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9
10THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/ThirdPartyLicenses/DotNetZip-bzip2.txt b/ThirdPartyLicenses/DotNetZip-bzip2.txt
new file mode 100644
index 0000000..f8b4346
--- /dev/null
+++ b/ThirdPartyLicenses/DotNetZip-bzip2.txt
@@ -0,0 +1,29 @@
1
2The managed BZIP2 code included in Ionic.BZip2.dll and Ionic.Zip.dll is
3modified code, based on the bzip2 code in the Apache commons compress
4library.
5
6The original BZip2 was created by Julian Seward, and is licensed under
7the BSD license.
8
9The following license applies to the Apache code:
10-----------------------------------------------------------------------
11
12/*
13 * Licensed to the Apache Software Foundation (ASF) under one
14 * or more contributor license agreements. See the NOTICE file
15 * distributed with this work for additional information
16 * regarding copyright ownership. The ASF licenses this file
17 * to you under the Apache License, Version 2.0 (the
18 * "License"); you may not use this file except in compliance
19 * with the License. You may obtain a copy of the License at
20 *
21 * http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing,
24 * software distributed under the License is distributed on an
25 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
26 * KIND, either express or implied. See the License for the
27 * specific language governing permissions and limitations
28 * under the License.
29 */
diff --git a/ThirdPartyLicenses/DotNetZip-zlib.txt b/ThirdPartyLicenses/DotNetZip-zlib.txt
new file mode 100644
index 0000000..801e941
--- /dev/null
+++ b/ThirdPartyLicenses/DotNetZip-zlib.txt
@@ -0,0 +1,70 @@
1
2The following licenses govern use of the accompanying software, the
3DotNetZip library ("the software"). If you use the software, you accept
4these licenses. If you do not accept the license, do not use the software.
5
6The managed ZLIB code included in Ionic.Zlib.dll and Ionic.Zip.dll is
7modified code, based on jzlib.
8
9
10
11The following notice applies to jzlib:
12-----------------------------------------------------------------------
13
14Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
15
16Redistribution and use in source and binary forms, with or without
17modification, are permitted provided that the following conditions are met:
18
191. Redistributions of source code must retain the above copyright notice,
20this list of conditions and the following disclaimer.
21
222. Redistributions in binary form must reproduce the above copyright
23notice, this list of conditions and the following disclaimer in
24the documentation and/or other materials provided with the distribution.
25
263. The names of the authors may not be used to endorse or promote products
27derived from this software without specific prior written permission.
28
29THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
30INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
32INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
33INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
35OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
37NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
38EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
40-----------------------------------------------------------------------
41
42jzlib is based on zlib-1.1.3.
43
44The following notice applies to zlib:
45
46-----------------------------------------------------------------------
47
48Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
49
50 The ZLIB software is provided 'as-is', without any express or implied
51 warranty. In no event will the authors be held liable for any damages
52 arising from the use of this software.
53
54 Permission is granted to anyone to use this software for any purpose,
55 including commercial applications, and to alter it and redistribute it
56 freely, subject to the following restrictions:
57
58 1. The origin of this software must not be misrepresented; you must not
59 claim that you wrote the original software. If you use this software
60 in a product, an acknowledgment in the product documentation would be
61 appreciated but is not required.
62 2. Altered source versions must be plainly marked as such, and must not be
63 misrepresented as being the original software.
64 3. This notice may not be removed or altered from any source distribution.
65
66 Jean-loup Gailly jloup@gzip.org
67 Mark Adler madler@alumni.caltech.edu
68
69
70-----------------------------------------------------------------------
diff --git a/ThirdPartyLicenses/DotNetZip.txt b/ThirdPartyLicenses/DotNetZip.txt
new file mode 100644
index 0000000..c3103fd
--- /dev/null
+++ b/ThirdPartyLicenses/DotNetZip.txt
@@ -0,0 +1,33 @@
1Microsoft Public License (Ms-PL)
2
3This license governs use of the accompanying software, the DotNetZip library ("the software"). If you use the software, you accept this license. If you do not accept the license, do not use the software.
4
51. Definitions
6
7The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
8
9A "contribution" is the original software, or any additions or changes to the software.
10
11A "contributor" is any person that distributes its contribution under this license.
12
13"Licensed patents" are a contributor's patent claims that read directly on its contribution.
14
152. Grant of Rights
16
17(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
18
19(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
20
213. Conditions and Limitations
22
23(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
24
25(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
26
27(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
28
29(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
30
31(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
32
33
diff --git a/ThirdPartyLicenses/GTCache.txt b/ThirdPartyLicenses/GTCache.txt
new file mode 100644
index 0000000..0e3496f
--- /dev/null
+++ b/ThirdPartyLicenses/GTCache.txt
@@ -0,0 +1,477 @@
1GlynnTucker.Cache
2
3http://gtcache.sourceforge.net/
4
5The GlynnTucker.Cache assembly provides a data structure for caching slow data retrievals, for example data retrieved from a database server over the network. Think of it as a Hashtable that can automatically expire its data after a set amount of time or a specified period of inactivity, on a per-object basis. It is written in C# and dual licensed under the GPL/MPL, it should work with any .NET language.
6
7
8 MOZILLA PUBLIC LICENSE
9 Version 1.1
10
11 ---------------
12
131. Definitions.
14
15 1.0.1. "Commercial Use" means distribution or otherwise making the
16 Covered Code available to a third party.
17
18 1.1. "Contributor" means each entity that creates or contributes to
19 the creation of Modifications.
20
21 1.2. "Contributor Version" means the combination of the Original
22 Code, prior Modifications used by a Contributor, and the Modifications
23 made by that particular Contributor.
24
25 1.3. "Covered Code" means the Original Code or Modifications or the
26 combination of the Original Code and Modifications, in each case
27 including portions thereof.
28
29 1.4. "Electronic Distribution Mechanism" means a mechanism generally
30 accepted in the software development community for the electronic
31 transfer of data.
32
33 1.5. "Executable" means Covered Code in any form other than Source
34 Code.
35
36 1.6. "Initial Developer" means the individual or entity identified
37 as the Initial Developer in the Source Code notice required by Exhibit
38 A.
39
40 1.7. "Larger Work" means a work which combines Covered Code or
41 portions thereof with code not governed by the terms of this License.
42
43 1.8. "License" means this document.
44
45 1.8.1. "Licensable" means having the right to grant, to the maximum
46 extent possible, whether at the time of the initial grant or
47 subsequently acquired, any and all of the rights conveyed herein.
48
49 1.9. "Modifications" means any addition to or deletion from the
50 substance or structure of either the Original Code or any previous
51 Modifications. When Covered Code is released as a series of files, a
52 Modification is:
53 A. Any addition to or deletion from the contents of a file
54 containing Original Code or previous Modifications.
55
56 B. Any new file that contains any part of the Original Code or
57 previous Modifications.
58
59 1.10. "Original Code" means Source Code of computer software code
60 which is described in the Source Code notice required by Exhibit A as
61 Original Code, and which, at the time of its release under this
62 License is not already Covered Code governed by this License.
63
64 1.10.1. "Patent Claims" means any patent claim(s), now owned or
65 hereafter acquired, including without limitation, method, process,
66 and apparatus claims, in any patent Licensable by grantor.
67
68 1.11. "Source Code" means the preferred form of the Covered Code for
69 making modifications to it, including all modules it contains, plus
70 any associated interface definition files, scripts used to control
71 compilation and installation of an Executable, or source code
72 differential comparisons against either the Original Code or another
73 well known, available Covered Code of the Contributor's choice. The
74 Source Code can be in a compressed or archival form, provided the
75 appropriate decompression or de-archiving software is widely available
76 for no charge.
77
78 1.12. "You" (or "Your") means an individual or a legal entity
79 exercising rights under, and complying with all of the terms of, this
80 License or a future version of this License issued under Section 6.1.
81 For legal entities, "You" includes any entity which controls, is
82 controlled by, or is under common control with You. For purposes of
83 this definition, "control" means (a) the power, direct or indirect,
84 to cause the direction or management of such entity, whether by
85 contract or otherwise, or (b) ownership of more than fifty percent
86 (50%) of the outstanding shares or beneficial ownership of such
87 entity.
88
892. Source Code License.
90
91 2.1. The Initial Developer Grant.
92 The Initial Developer hereby grants You a world-wide, royalty-free,
93 non-exclusive license, subject to third party intellectual property
94 claims:
95 (a) under intellectual property rights (other than patent or
96 trademark) Licensable by Initial Developer to use, reproduce,
97 modify, display, perform, sublicense and distribute the Original
98 Code (or portions thereof) with or without Modifications, and/or
99 as part of a Larger Work; and
100
101 (b) under Patents Claims infringed by the making, using or
102 selling of Original Code, to make, have made, use, practice,
103 sell, and offer for sale, and/or otherwise dispose of the
104 Original Code (or portions thereof).
105
106 (c) the licenses granted in this Section 2.1(a) and (b) are
107 effective on the date Initial Developer first distributes
108 Original Code under the terms of this License.
109
110 (d) Notwithstanding Section 2.1(b) above, no patent license is
111 granted: 1) for code that You delete from the Original Code; 2)
112 separate from the Original Code; or 3) for infringements caused
113 by: i) the modification of the Original Code or ii) the
114 combination of the Original Code with other software or devices.
115
116 2.2. Contributor Grant.
117 Subject to third party intellectual property claims, each Contributor
118 hereby grants You a world-wide, royalty-free, non-exclusive license
119
120 (a) under intellectual property rights (other than patent or
121 trademark) Licensable by Contributor, to use, reproduce, modify,
122 display, perform, sublicense and distribute the Modifications
123 created by such Contributor (or portions thereof) either on an
124 unmodified basis, with other Modifications, as Covered Code
125 and/or as part of a Larger Work; and
126
127 (b) under Patent Claims infringed by the making, using, or
128 selling of Modifications made by that Contributor either alone
129 and/or in combination with its Contributor Version (or portions
130 of such combination), to make, use, sell, offer for sale, have
131 made, and/or otherwise dispose of: 1) Modifications made by that
132 Contributor (or portions thereof); and 2) the combination of
133 Modifications made by that Contributor with its Contributor
134 Version (or portions of such combination).
135
136 (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
137 effective on the date Contributor first makes Commercial Use of
138 the Covered Code.
139
140 (d) Notwithstanding Section 2.2(b) above, no patent license is
141 granted: 1) for any code that Contributor has deleted from the
142 Contributor Version; 2) separate from the Contributor Version;
143 3) for infringements caused by: i) third party modifications of
144 Contributor Version or ii) the combination of Modifications made
145 by that Contributor with other software (except as part of the
146 Contributor Version) or other devices; or 4) under Patent Claims
147 infringed by Covered Code in the absence of Modifications made by
148 that Contributor.
149
1503. Distribution Obligations.
151
152 3.1. Application of License.
153 The Modifications which You create or to which You contribute are
154 governed by the terms of this License, including without limitation
155 Section 2.2. The Source Code version of Covered Code may be
156 distributed only under the terms of this License or a future version
157 of this License released under Section 6.1, and You must include a
158 copy of this License with every copy of the Source Code You
159 distribute. You may not offer or impose any terms on any Source Code
160 version that alters or restricts the applicable version of this
161 License or the recipients' rights hereunder. However, You may include
162 an additional document offering the additional rights described in
163 Section 3.5.
164
165 3.2. Availability of Source Code.
166 Any Modification which You create or to which You contribute must be
167 made available in Source Code form under the terms of this License
168 either on the same media as an Executable version or via an accepted
169 Electronic Distribution Mechanism to anyone to whom you made an
170 Executable version available; and if made available via Electronic
171 Distribution Mechanism, must remain available for at least twelve (12)
172 months after the date it initially became available, or at least six
173 (6) months after a subsequent version of that particular Modification
174 has been made available to such recipients. You are responsible for
175 ensuring that the Source Code version remains available even if the
176 Electronic Distribution Mechanism is maintained by a third party.
177
178 3.3. Description of Modifications.
179 You must cause all Covered Code to which You contribute to contain a
180 file documenting the changes You made to create that Covered Code and
181 the date of any change. You must include a prominent statement that
182 the Modification is derived, directly or indirectly, from Original
183 Code provided by the Initial Developer and including the name of the
184 Initial Developer in (a) the Source Code, and (b) in any notice in an
185 Executable version or related documentation in which You describe the
186 origin or ownership of the Covered Code.
187
188 3.4. Intellectual Property Matters
189 (a) Third Party Claims.
190 If Contributor has knowledge that a license under a third party's
191 intellectual property rights is required to exercise the rights
192 granted by such Contributor under Sections 2.1 or 2.2,
193 Contributor must include a text file with the Source Code
194 distribution titled "LEGAL" which describes the claim and the
195 party making the claim in sufficient detail that a recipient will
196 know whom to contact. If Contributor obtains such knowledge after
197 the Modification is made available as described in Section 3.2,
198 Contributor shall promptly modify the LEGAL file in all copies
199 Contributor makes available thereafter and shall take other steps
200 (such as notifying appropriate mailing lists or newsgroups)
201 reasonably calculated to inform those who received the Covered
202 Code that new knowledge has been obtained.
203
204 (b) Contributor APIs.
205 If Contributor's Modifications include an application programming
206 interface and Contributor has knowledge of patent licenses which
207 are reasonably necessary to implement that API, Contributor must
208 also include this information in the LEGAL file.
209
210 (c) Representations.
211 Contributor represents that, except as disclosed pursuant to
212 Section 3.4(a) above, Contributor believes that Contributor's
213 Modifications are Contributor's original creation(s) and/or
214 Contributor has sufficient rights to grant the rights conveyed by
215 this License.
216
217 3.5. Required Notices.
218 You must duplicate the notice in Exhibit A in each file of the Source
219 Code. If it is not possible to put such notice in a particular Source
220 Code file due to its structure, then You must include such notice in a
221 location (such as a relevant directory) where a user would be likely
222 to look for such a notice. If You created one or more Modification(s)
223 You may add your name as a Contributor to the notice described in
224 Exhibit A. You must also duplicate this License in any documentation
225 for the Source Code where You describe recipients' rights or ownership
226 rights relating to Covered Code. You may choose to offer, and to
227 charge a fee for, warranty, support, indemnity or liability
228 obligations to one or more recipients of Covered Code. However, You
229 may do so only on Your own behalf, and not on behalf of the Initial
230 Developer or any Contributor. You must make it absolutely clear than
231 any such warranty, support, indemnity or liability obligation is
232 offered by You alone, and You hereby agree to indemnify the Initial
233 Developer and every Contributor for any liability incurred by the
234 Initial Developer or such Contributor as a result of warranty,
235 support, indemnity or liability terms You offer.
236
237 3.6. Distribution of Executable Versions.
238 You may distribute Covered Code in Executable form only if the
239 requirements of Section 3.1-3.5 have been met for that Covered Code,
240 and if You include a notice stating that the Source Code version of
241 the Covered Code is available under the terms of this License,
242 including a description of how and where You have fulfilled the
243 obligations of Section 3.2. The notice must be conspicuously included
244 in any notice in an Executable version, related documentation or
245 collateral in which You describe recipients' rights relating to the
246 Covered Code. You may distribute the Executable version of Covered
247 Code or ownership rights under a license of Your choice, which may
248 contain terms different from this License, provided that You are in
249 compliance with the terms of this License and that the license for the
250 Executable version does not attempt to limit or alter the recipient's
251 rights in the Source Code version from the rights set forth in this
252 License. If You distribute the Executable version under a different
253 license You must make it absolutely clear that any terms which differ
254 from this License are offered by You alone, not by the Initial
255 Developer or any Contributor. You hereby agree to indemnify the
256 Initial Developer and every Contributor for any liability incurred by
257 the Initial Developer or such Contributor as a result of any such
258 terms You offer.
259
260 3.7. Larger Works.
261 You may create a Larger Work by combining Covered Code with other code
262 not governed by the terms of this License and distribute the Larger
263 Work as a single product. In such a case, You must make sure the
264 requirements of this License are fulfilled for the Covered Code.
265
2664. Inability to Comply Due to Statute or Regulation.
267
268 If it is impossible for You to comply with any of the terms of this
269 License with respect to some or all of the Covered Code due to
270 statute, judicial order, or regulation then You must: (a) comply with
271 the terms of this License to the maximum extent possible; and (b)
272 describe the limitations and the code they affect. Such description
273 must be included in the LEGAL file described in Section 3.4 and must
274 be included with all distributions of the Source Code. Except to the
275 extent prohibited by statute or regulation, such description must be
276 sufficiently detailed for a recipient of ordinary skill to be able to
277 understand it.
278
2795. Application of this License.
280
281 This License applies to code to which the Initial Developer has
282 attached the notice in Exhibit A and to related Covered Code.
283
2846. Versions of the License.
285
286 6.1. New Versions.
287 Netscape Communications Corporation ("Netscape") may publish revised
288 and/or new versions of the License from time to time. Each version
289 will be given a distinguishing version number.
290
291 6.2. Effect of New Versions.
292 Once Covered Code has been published under a particular version of the
293 License, You may always continue to use it under the terms of that
294 version. You may also choose to use such Covered Code under the terms
295 of any subsequent version of the License published by Netscape. No one
296 other than Netscape has the right to modify the terms applicable to
297 Covered Code created under this License.
298
299 6.3. Derivative Works.
300 If You create or use a modified version of this License (which you may
301 only do in order to apply it to code which is not already Covered Code
302 governed by this License), You must (a) rename Your license so that
303 the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
304 "MPL", "NPL" or any confusingly similar phrase do not appear in your
305 license (except to note that your license differs from this License)
306 and (b) otherwise make it clear that Your version of the license
307 contains terms which differ from the Mozilla Public License and
308 Netscape Public License. (Filling in the name of the Initial
309 Developer, Original Code or Contributor in the notice described in
310 Exhibit A shall not of themselves be deemed to be modifications of
311 this License.)
312
3137. DISCLAIMER OF WARRANTY.
314
315 COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
316 WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
317 WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
318 DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
319 THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
320 IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
321 YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
322 COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
323 OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
324 ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
325
3268. TERMINATION.
327
328 8.1. This License and the rights granted hereunder will terminate
329 automatically if You fail to comply with terms herein and fail to cure
330 such breach within 30 days of becoming aware of the breach. All
331 sublicenses to the Covered Code which are properly granted shall
332 survive any termination of this License. Provisions which, by their
333 nature, must remain in effect beyond the termination of this License
334 shall survive.
335
336 8.2. If You initiate litigation by asserting a patent infringement
337 claim (excluding declatory judgment actions) against Initial Developer
338 or a Contributor (the Initial Developer or Contributor against whom
339 You file such action is referred to as "Participant") alleging that:
340
341 (a) such Participant's Contributor Version directly or indirectly
342 infringes any patent, then any and all rights granted by such
343 Participant to You under Sections 2.1 and/or 2.2 of this License
344 shall, upon 60 days notice from Participant terminate prospectively,
345 unless if within 60 days after receipt of notice You either: (i)
346 agree in writing to pay Participant a mutually agreeable reasonable
347 royalty for Your past and future use of Modifications made by such
348 Participant, or (ii) withdraw Your litigation claim with respect to
349 the Contributor Version against such Participant. If within 60 days
350 of notice, a reasonable royalty and payment arrangement are not
351 mutually agreed upon in writing by the parties or the litigation claim
352 is not withdrawn, the rights granted by Participant to You under
353 Sections 2.1 and/or 2.2 automatically terminate at the expiration of
354 the 60 day notice period specified above.
355
356 (b) any software, hardware, or device, other than such Participant's
357 Contributor Version, directly or indirectly infringes any patent, then
358 any rights granted to You by such Participant under Sections 2.1(b)
359 and 2.2(b) are revoked effective as of the date You first made, used,
360 sold, distributed, or had made, Modifications made by that
361 Participant.
362
363 8.3. If You assert a patent infringement claim against Participant
364 alleging that such Participant's Contributor Version directly or
365 indirectly infringes any patent where such claim is resolved (such as
366 by license or settlement) prior to the initiation of patent
367 infringement litigation, then the reasonable value of the licenses
368 granted by such Participant under Sections 2.1 or 2.2 shall be taken
369 into account in determining the amount or value of any payment or
370 license.
371
372 8.4. In the event of termination under Sections 8.1 or 8.2 above,
373 all end user license agreements (excluding distributors and resellers)
374 which have been validly granted by You or any distributor hereunder
375 prior to termination shall survive termination.
376
3779. LIMITATION OF LIABILITY.
378
379 UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
380 (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
381 DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
382 OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
383 ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
384 CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
385 WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
386 COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
387 INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
388 LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
389 RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
390 PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
391 EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
392 THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
393
39410. U.S. GOVERNMENT END USERS.
395
396 The Covered Code is a "commercial item," as that term is defined in
397 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
398 software" and "commercial computer software documentation," as such
399 terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
400 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
401 all U.S. Government End Users acquire Covered Code with only those
402 rights set forth herein.
403
40411. MISCELLANEOUS.
405
406 This License represents the complete agreement concerning subject
407 matter hereof. If any provision of this License is held to be
408 unenforceable, such provision shall be reformed only to the extent
409 necessary to make it enforceable. This License shall be governed by
410 California law provisions (except to the extent applicable law, if
411 any, provides otherwise), excluding its conflict-of-law provisions.
412 With respect to disputes in which at least one party is a citizen of,
413 or an entity chartered or registered to do business in the United
414 States of America, any litigation relating to this License shall be
415 subject to the jurisdiction of the Federal Courts of the Northern
416 District of California, with venue lying in Santa Clara County,
417 California, with the losing party responsible for costs, including
418 without limitation, court costs and reasonable attorneys' fees and
419 expenses. The application of the United Nations Convention on
420 Contracts for the International Sale of Goods is expressly excluded.
421 Any law or regulation which provides that the language of a contract
422 shall be construed against the drafter shall not apply to this
423 License.
424
42512. RESPONSIBILITY FOR CLAIMS.
426
427 As between Initial Developer and the Contributors, each party is
428 responsible for claims and damages arising, directly or indirectly,
429 out of its utilization of rights under this License and You agree to
430 work with Initial Developer and Contributors to distribute such
431 responsibility on an equitable basis. Nothing herein is intended or
432 shall be deemed to constitute any admission of liability.
433
43413. MULTIPLE-LICENSED CODE.
435
436 Initial Developer may designate portions of the Covered Code as
437 "Multiple-Licensed". "Multiple-Licensed" means that the Initial
438 Developer permits you to utilize portions of the Covered Code under
439 Your choice of the NPL or the alternative licenses, if any, specified
440 by the Initial Developer in the file described in Exhibit A.
441
442EXHIBIT A -Mozilla Public License.
443
444 ``The contents of this file are subject to the Mozilla Public License
445 Version 1.1 (the "License"); you may not use this file except in
446 compliance with the License. You may obtain a copy of the License at
447 http://www.mozilla.org/MPL/
448
449 Software distributed under the License is distributed on an "AS IS"
450 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
451 License for the specific language governing rights and limitations
452 under the License.
453
454 The Original Code is ______________________________________.
455
456 The Initial Developer of the Original Code is ________________________.
457 Portions created by ______________________ are Copyright (C) ______
458 _______________________. All Rights Reserved.
459
460 Contributor(s): ______________________________________.
461
462 Alternatively, the contents of this file may be used under the terms
463 of the _____ license (the "[___] License"), in which case the
464 provisions of [______] License are applicable instead of those
465 above. If you wish to allow use of your version of this file only
466 under the terms of the [____] License and not to allow others to use
467 your version of this file under the MPL, indicate your decision by
468 deleting the provisions above and replace them with the notice and
469 other provisions required by the [___] License. If you do not delete
470 the provisions above, a recipient may use your version of this file
471 under either the MPL or the [___] License."
472
473 [NOTE: The text of this Exhibit A may differ slightly from the text of
474 the notices in the Source Code files of the Original Code. You should
475 use the text of this Exhibit A rather than the text found in the
476 Original Code Source Code for Your Modifications.]
477
diff --git a/ThirdPartyLicenses/GoogleProtoBuffer.txt b/ThirdPartyLicenses/GoogleProtoBuffer.txt
new file mode 100644
index 0000000..e0df00c
--- /dev/null
+++ b/ThirdPartyLicenses/GoogleProtoBuffer.txt
@@ -0,0 +1,31 @@
1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// http://github.com/jskeet/dotnet-protobufs/
4// Original C++/Java/Python code:
5// http://code.google.com/p/protobuf/
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
10//
11// * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17// * Neither the name of Google Inc. nor the names of its
18// contributors may be used to endorse or promote products derived from
19// this software without specific prior written permission.
20//
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/ThirdPartyLicenses/ICSharpCode.SharpZipLib.license.txt b/ThirdPartyLicenses/ICSharpCode.SharpZipLib.license.txt
new file mode 100644
index 0000000..c384be4
--- /dev/null
+++ b/ThirdPartyLicenses/ICSharpCode.SharpZipLib.license.txt
@@ -0,0 +1,17 @@
1The library is released under the GPL with the following exception:
2
3Linking this library statically or dynamically with other modules is
4making a combined work based on this library. Thus, the terms and
5conditions of the GNU General Public License cover the whole combination.
6
7As a special exception, the copyright holders of this library give you
8permission to link this library with independent modules to produce an
9executable, regardless of the license terms of these independent modules,
10and to copy and distribute the resulting executable under terms of your
11choice, provided that you also meet, for each linked independent module,
12the terms and conditions of the license of that module. An independent
13module is a module which is not derived from or based on this library.
14
15If you modify this library, you may extend this exception to your
16version of the library, but you are not obligated to do so. If you do not
17wish to do so, delete this exception statement from your version.
diff --git a/ThirdPartyLicenses/MXP.txt b/ThirdPartyLicenses/MXP.txt
new file mode 100644
index 0000000..43f51ce
--- /dev/null
+++ b/ThirdPartyLicenses/MXP.txt
@@ -0,0 +1,15 @@
1Metaverse Exchange Protocol specification and reference implementation.
2
3Copyright 2008-2009 Bubble Cloud Comminity (http://www.bubblecloud.org)
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
diff --git a/ThirdPartyLicenses/Mono.Xna (MonoXnaCompactMaths).txt b/ThirdPartyLicenses/Mono.Xna (MonoXnaCompactMaths).txt
new file mode 100644
index 0000000..ef324b6
--- /dev/null
+++ b/ThirdPartyLicenses/Mono.Xna (MonoXnaCompactMaths).txt
@@ -0,0 +1,22 @@
1MIT License
2Copyright © 2006 The Mono.Xna Team
3
4All rights reserved.
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE. \ No newline at end of file
diff --git a/ThirdPartyLicenses/MonoAddins.txt b/ThirdPartyLicenses/MonoAddins.txt
new file mode 100644
index 0000000..10c23b3
--- /dev/null
+++ b/ThirdPartyLicenses/MonoAddins.txt
@@ -0,0 +1,41 @@
1Authors: Lluis Sanchez Gual <lluis@novell.com>
2
3The MIT License
4
5Copyright (C) 2007 Novell, Inc (http://www.novell.com)
6
7
8
9Permission is hereby granted, free of charge, to any person obtaining
10a copy
11 of this software and associated documentation files (the "Software"),
12to deal
13 in the Software without restriction, including without limitation
14the rights
15to use, copy, modify, merge, publish, distribute, sublicense,
16and/or sell
17copies of the Software, and to permit persons to whom the
18Software is
19furnished to do so, subject to the following conditions:
20
21
22
23The above copyright notice and this permission notice shall be included in
24
25all copies or substantial portions of the Software.
26
27
28
29THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30EXPRESS OR
31IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32MERCHANTABILITY,
33FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT.
34IN NO EVENT SHALL THE
35AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
36DAMAGES OR OTHER
37LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
38OTHERWISE, ARISING FROM,
39OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
40THE USE OR OTHER DEALINGS IN
41THE SOFTWARE.
diff --git a/ThirdPartyLicenses/MySQL.txt b/ThirdPartyLicenses/MySQL.txt
new file mode 100644
index 0000000..bbda936
--- /dev/null
+++ b/ThirdPartyLicenses/MySQL.txt
@@ -0,0 +1,122 @@
1GPLv2 + MySQL FLOSS License Exception (files COPYING and EXCEPTIONS)
2
3--- file: EXCEPTIONS ---
4MySQL FLOSS License Exception
5
6The MySQL AB Exception for Free/Libre and Open Source
7Software-only Applications Using MySQL Client Libraries (the
8"FLOSS Exception").
9
10Version 0.6, 7 March 2007
11
12Exception Intent
13
14We want specified Free/Libre and Open Source Software (``FLOSS'')
15applications to be able to use specified GPL-licensed MySQL client
16libraries (the ``Program'') despite the fact that not all FLOSS
17licenses are compatible with version 2 of the GNU General Public
18License (the ``GPL'').
19
20Legal Terms and Conditions
21
22As a special exception to the terms and conditions of version 2.0
23of the GPL:
24
25 1. You are free to distribute a Derivative Work that is formed
26 entirely from the Program and one or more works (each, a
27 "FLOSS Work") licensed under one or more of the licenses
28 listed below in section 1, as long as:
29 a. You obey the GPL in all respects for the Program and the
30 Derivative Work, except for identifiable sections of the
31 Derivative Work which are not derived from the Program,
32 and which can reasonably be considered independent and
33 separate works in themselves,
34 b. all identifiable sections of the Derivative Work which
35 are not derived from the Program, and which can
36 reasonably be considered independent and separate works
37 in themselves,
38 i. are distributed subject to one of the FLOSS licenses
39 listed below, and
40 ii. the object code or executable form of those sections
41 are accompanied by the complete corresponding
42 machine-readable source code for those sections on
43 the same medium and under the same FLOSS license as
44 the corresponding object code or executable forms of
45 those sections, and
46 c. any works which are aggregated with the Program or with a
47 Derivative Work on a volume of a storage or distribution
48 medium in accordance with the GPL, can reasonably be
49 considered independent and separate works in themselves
50 which are not derivatives of either the Program, a
51 Derivative Work or a FLOSS Work.
52 If the above conditions are not met, then the Program may only
53 be copied, modified, distributed or used under the terms and
54 conditions of the GPL or another valid licensing option from
55 MySQL AB.
56
57 2. FLOSS License List
58
59License name Version(s)/Copyright Date
60Academic Free License 2.0
61Apache Software License 1.0/1.1/2.0
62Apple Public Source License 2.0
63Artistic license From Perl 5.8.0
64BSD license "July 22 1999"
65Common Development and Distribution License (CDDL) 1.0
66Common Public License 1.0
67Eclipse Public License 1.0
68GNU Library or "Lesser" General Public License (LGPL) 2.0/2.1
69Jabber Open Source License 1.0
70MIT license (As listed in file MIT-License.txt) ---
71Mozilla Public License (MPL) 1.0/1.1
72Open Software License 2.0
73OpenSSL license (with original SSLeay license) "2003" ("1998")
74PHP License 3.0
75Python license (CNRI Python License) ---
76Python Software Foundation License 2.1.1
77Sleepycat License "1999"
78University of Illinois/NCSA Open Source License ---
79W3C License "2001"
80X11 License "2001"
81Zlib/libpng License ---
82Zope Public License 2.0
83
84 Due to the many variants of some of the above licenses, we
85 require that any version follow the 2003 version of the Free
86 Software Foundation's Free Software Definition
87 (http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of
88 the Open Source Definition by the Open Source Initiative
89 (http://www.opensource.org/docs/definition.php).
90
91 3. Definitions
92
93 a. Terms used, but not defined, herein shall have the
94 meaning provided in the GPL.
95 b. Derivative Work means a derivative work under copyright
96 law.
97
98 4. Applicability: This FLOSS Exception applies to all Programs
99 that contain a notice placed by MySQL AB saying that the
100 Program may be distributed under the terms of this FLOSS
101 Exception. If you create or distribute a work which is a
102 Derivative Work of both the Program and any other work
103 licensed under the GPL, then this FLOSS Exception is not
104 available for that work; thus, you must remove the FLOSS
105 Exception notice from that work and comply with the GPL in all
106 respects, including by retaining all GPL notices. You may
107 choose to redistribute a copy of the Program exclusively under
108 the terms of the GPL by removing the FLOSS Exception notice
109 from that copy of the Program, provided that the copy has
110 never been modified by you or any third party.
111
112Appendix A. Qualified Libraries and Packages
113
114The following is a non-exhaustive list of libraries and packages
115which are covered by the FLOSS License Exception. Please note that
116this appendix is provided merely as an additional service to
117specific FLOSS projects wishing to simplify licensing information
118for their users. Compliance with one of the licenses noted under
119the "FLOSS license list" section remains a prerequisite.
120
121Package Name Qualifying License and Version
122Apache Portable Runtime (APR) Apache Software License 2.0
diff --git a/ThirdPartyLicenses/Nini.txt b/ThirdPartyLicenses/Nini.txt
new file mode 100644
index 0000000..fe38b62
--- /dev/null
+++ b/ThirdPartyLicenses/Nini.txt
@@ -0,0 +1,23 @@
1
2Nini Configuration Project.
3Copyright (c) 2006 Brent R. Matzelle
4
5Permission is hereby granted, free of charge, to any person obtaining
6a copy of this software and associated documentation files (the
7"Software"), to deal in the Software without restriction, including
8without limitation the rights to use, copy, modify, merge, publish,
9distribute, sublicense, and/or sell copies of the Software, and to
10permit persons to whom the Software is furnished to do so, subject to
11the following conditions:
12
13The above copyright notice and this permission notice shall be
14included in all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
diff --git a/ThirdPartyLicenses/Npgsql.txt b/ThirdPartyLicenses/Npgsql.txt
new file mode 100644
index 0000000..e2e4f12
--- /dev/null
+++ b/ThirdPartyLicenses/Npgsql.txt
@@ -0,0 +1,7 @@
1Copyright (c) 2002-2007, The Npgsql Development Team
2
3Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies.
4
5IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6
7THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
diff --git a/ThirdPartyLicenses/ODE.txt b/ThirdPartyLicenses/ODE.txt
new file mode 100644
index 0000000..53a93db
--- /dev/null
+++ b/ThirdPartyLicenses/ODE.txt
@@ -0,0 +1,13 @@
1Open Dynamics Engine
2Copyright (c) 2001-2004, Russell L. Smith.
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
7Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8
9Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10
11Neither the names of ODE's copyright owner nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
12
13THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/ThirdPartyLicenses/OpenJpeg.txt b/ThirdPartyLicenses/OpenJpeg.txt
new file mode 100644
index 0000000..d1e5b6a
--- /dev/null
+++ b/ThirdPartyLicenses/OpenJpeg.txt
@@ -0,0 +1,30 @@
1/*
2 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3 * Copyright (c) 2002-2007, Professor Benoit Macq
4 * Copyright (c) 2001-2003, David Janssens
5 * Copyright (c) 2002-2003, Yannick Verschueren
6 * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
7 * Copyright (c) 2005, Herve Drolon, FreeImage Team
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */ \ No newline at end of file
diff --git a/ThirdPartyLicenses/Protobuf-net.txt b/ThirdPartyLicenses/Protobuf-net.txt
new file mode 100644
index 0000000..8eb6c71
--- /dev/null
+++ b/ThirdPartyLicenses/Protobuf-net.txt
@@ -0,0 +1,21 @@
1The core Protocol Buffers technology is provided courtesy of Google.
2At the time of writing, this is released under the BSD license.
3Full details can be found here:
4
5http://code.google.com/p/protobuf/
6
7
8This .NET implementation is Copyright 2008 Marc Gravell
9
10 Licensed under the Apache License, Version 2.0 (the "License");
11 you may not use this file except in compliance with the License.
12 You may obtain a copy of the License at
13
14 http://www.apache.org/licenses/LICENSE-2.0
15
16 Unless required by applicable law or agreed to in writing, software
17 distributed under the License is distributed on an "AS IS" BASIS,
18 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 See the License for the specific language governing permissions and
20 limitations under the License.
21
diff --git a/ThirdPartyLicenses/Prototype.txt b/ThirdPartyLicenses/Prototype.txt
new file mode 100644
index 0000000..61e4918
--- /dev/null
+++ b/ThirdPartyLicenses/Prototype.txt
@@ -0,0 +1,16 @@
1Copyright (c) 2005-2008 Sam Stephenson
2
3Permission is hereby granted, free of charge, to any person obtaining a copy
4of this software and associated documentation files (the "Software"), to deal
5in the Software without restriction, including without limitation the rights
6to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7copies of the Software, and to permit persons to whom the Software is
8furnished to do so, subject to the following conditions:
9
10THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16SOFTWARE.
diff --git a/ThirdPartyLicenses/SmartThreadPool.txt b/ThirdPartyLicenses/SmartThreadPool.txt
new file mode 100644
index 0000000..7bfc997
--- /dev/null
+++ b/ThirdPartyLicenses/SmartThreadPool.txt
@@ -0,0 +1,22 @@
1Microsoft Public License (Ms-PL)
2
3This license governs use of the accompanying software. If you use the software, you
4accept this license. If you do not accept the license, do not use the software.
5
61. Definitions
7The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
8same meaning here as under U.S. copyright law.
9A "contribution" is the original software, or any additions or changes to the software.
10A "contributor" is any person that distributes its contribution under this license.
11"Licensed patents" are a contributor's patent claims that read directly on its contribution.
12
132. Grant of Rights
14(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
15(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
16
173. Conditions and Limitations
18(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
19(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
20(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
21(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
22(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
diff --git a/ThirdPartyLicenses/XML-RPC.NET.txt b/ThirdPartyLicenses/XML-RPC.NET.txt
new file mode 100644
index 0000000..2aff37f
--- /dev/null
+++ b/ThirdPartyLicenses/XML-RPC.NET.txt
@@ -0,0 +1,27 @@
1XML-RPC.NET - XML-RPC for .NET
2v2.1.0
3Copyright (C) 2001-2006 Charles Cook (chascook@gmail.com)
4
5xmlrpcgen
6Copyright (C) 2003 Joe Bork
7
8For more information about XML-RPC.NET visit http://www.xml-rpc.net.
9
10XML-RPC.NET is licensed with MIT X11 license.
11(see http://www.xml-rpc.net/faq/xmlrpcnetfaq.html#6.12)
12
13For more information about XML-RPC refer to http://www.xmlrpc.com/
14
15
16PREQUISITES
17-----------
18Assembly CookComputing.XmlRpc.dll requires 1.0 .NET runtime and
19runs on all later versions.
20
21Assembly CookComputing.XmlRpcV2.dll requires 2.0 .NET runtime.
22
23
24DOCUMENTATION
25-------------
26For help on using XML-RPC.NET, see
27http://www.xml-rpc.net/faq/xmlrpcnetfaq.html. \ No newline at end of file
diff --git a/ThirdPartyLicenses/libsl.txt b/ThirdPartyLicenses/libsl.txt
new file mode 100644
index 0000000..73951dc
--- /dev/null
+++ b/ThirdPartyLicenses/libsl.txt
@@ -0,0 +1,23 @@
1Copyright (c) 2006, Second Life Reverse Engineering Team
2All rights reserved.
3
4- Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6
7- Redistributions of source code must retain the above copyright notice, this
8 list of conditions and the following disclaimer.
9- Neither the name of the Second Life Reverse Engineering Team nor the names
10 of its contributors may be used to endorse or promote products derived from
11 this software without specific prior written permission.
12
13THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
17LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file