We really want to use system threads because ideally this all becomes cases where we use the language construct async/await and we dont want conflicts. Also some of the stats interfaces in use are deprecated and no sense in fixing them.
Some checks failed
CodeQL / Analyze (push) Has been cancelled
dotnet package / build (8.0.x) (push) Has been cancelled
dotnet package / build (9.0.x) (push) Has been cancelled

This commit is contained in:
Mike Dickson 2024-11-16 10:57:24 -05:00
parent c75a30c37d
commit 08197ec4f6
63 changed files with 3 additions and 7156 deletions

View file

@ -188,16 +188,6 @@ namespace OpenSim.Framework.Monitoring
s.Value = iocpThreads;
});
if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool && Util.GetSmartThreadPoolInfo() != null)
{
MakeStat("STPMaxThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().MaxThreads);
MakeStat("STPMinThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().MinThreads);
MakeStat("STPConcurrency", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().MaxConcurrentWorkItems);
MakeStat("STPActiveThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().ActiveThreads);
MakeStat("STPInUseThreads", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().InUseThreads);
MakeStat("STPWorkItemsWaiting", null, "threads", ContainerThreadpool, s => s.Value = Util.GetSmartThreadPoolInfo().WaitingCallbacks);
}
MakeStat(
"HTTPRequestsMade",
"Number of outbound HTTP requests made",

View file

@ -239,7 +239,6 @@ namespace OpenSim.Framework.Monitoring
else
args["Error"] = "No Region data";
args["Util Thread Count"] = OSD.FromString(String.Format("{0:0.##}", Util.GetSmartThreadPoolInfo().InUseThreads));
args["System Thread Count"] = OSD.FromString(String.Format("{0:0.##}", numberThreads));
args["System Thread Active"] = OSD.FromString(String.Format("{0:0.##}", numberThreadsRunning));
args["ProcMem"] = OSD.FromString(String.Format("{0:0.##}", memUsage));

View file

@ -25,14 +25,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Threading;
using System.Reflection;
using log4net;
using OpenSim.Framework.Monitoring;
using Amib.Threading;
using System.Collections.Generic;
using System.Collections.Concurrent;
namespace OpenSim.Framework.Servers.HttpServer

View file

@ -137,7 +137,6 @@ namespace OpenSim.Framework.Servers
MainServer.Stop();
Thread.Sleep(500);
Util.StopThreadPool();
WorkManager.Stop();
RemovePIDFile();

View file

@ -891,22 +891,6 @@ namespace OpenSim.Framework.Servers
int inUseThreads = 0;
int waitingCallbacks = 0;
if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
{
STPInfo stpi = Util.GetSmartThreadPoolInfo();
// ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
if (stpi != null)
{
threadPoolUsed = "SmartThreadPool";
maxThreads = stpi.MaxThreads;
minThreads = stpi.MinThreads;
inUseThreads = stpi.InUseThreads;
allocatedThreads = stpi.ActiveThreads;
waitingCallbacks = stpi.WaitingCallbacks;
}
}
if (threadPoolUsed != null)
{
sb.Append("\nThreadpool (excluding script engine pools)\n");

View file

@ -26,9 +26,6 @@
<HintPath>..\..\Library\XMLRPC.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ThirdParty\SmartThreadPool\SmartThreadPool.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="3.0.1" />
<PackageReference Include="Mono.Addins" Version="1.4.1" />

View file

@ -53,7 +53,6 @@ using Nini.Config;
using Nwc.XmlRpc;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using Amib.Threading;
using System.Collections.Concurrent;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
@ -113,29 +112,9 @@ namespace OpenSim.Framework
None,
RegressionTest,
QueueUserWorkItem,
SmartThreadPool,
Thread
}
/// <summary>
/// Class for delivering SmartThreadPool statistical information
/// </summary>
/// <remarks>
/// We do it this way so that we do not directly expose STP.
/// </remarks>
public class STPInfo
{
public string Name;
public bool IsIdle;
public bool IsShuttingDown;
public int MaxThreads;
public int MinThreads;
public int InUseThreads;
public int ActiveThreads;
public int WaitingCallbacks;
public int MaxConcurrentWorkItems;
}
/// <summary>
/// Miscellaneous utility functions
/// </summary>
@ -192,11 +171,6 @@ namespace OpenSim.Framework
MaxCharactersInDocument = 10_000_000
};
/// <summary>
/// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used
/// </summary>
private static SmartThreadPool m_ThreadPool;
// Watchdog timer that aborts threads that have timed-out
private static Timer m_threadPoolWatchdog;
@ -209,7 +183,7 @@ namespace OpenSim.Framework
public static readonly Regex PermissiveUUIDPattern = new(rawUUIDPattern);
public static readonly Regex UUIDPattern = new(string.Format("^{0}$", rawUUIDPattern));
public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.Thread;
public static FireAndForgetMethod FireAndForgetMethod = DefaultFireAndForgetMethod;
public static readonly string UUIDZeroString = UUID.Zero.ToString();
@ -3245,33 +3219,6 @@ namespace OpenSim.Framework
#region FireAndForget Threading Pattern
public static void InitThreadPool(int minThreads, int maxThreads)
{
if (maxThreads < 2)
throw new ArgumentOutOfRangeException(nameof(maxThreads), "maxThreads must be greater than 2");
if (minThreads > maxThreads || minThreads < 2)
throw new ArgumentOutOfRangeException(nameof(minThreads), "minThreads must be greater than 2 and less than or equal to maxThreads");
if (m_ThreadPool != null)
{
m_log.Warn("SmartThreadPool is already initialized. Ignoring request.");
return;
}
STPStartInfo startInfo = new()
{
ThreadPoolName = "Util",
IdleTimeout = 20000,
MaxWorkerThreads = maxThreads,
MinWorkerThreads = minThreads,
SuppressFlow = true
};
m_ThreadPool = new SmartThreadPool(startInfo);
m_threadPoolWatchdog = new Timer(ThreadPoolWatchdog, null, 0, 1000);
}
public static int FireAndForgetCount()
{
const int MAX_SYSTEM_THREADS = 200;
@ -3281,13 +3228,13 @@ namespace OpenSim.Framework
case FireAndForgetMethod.QueueUserWorkItem:
ThreadPool.GetAvailableThreads(out int workerThreads, out _);
return workerThreads;
case FireAndForgetMethod.SmartThreadPool:
return m_ThreadPool.MaxThreads - m_ThreadPool.InUseThreads;
case FireAndForgetMethod.Thread:
{
using Process p = System.Diagnostics.Process.GetCurrentProcess();
return MAX_SYSTEM_THREADS - p.Threads.Count;
}
default:
throw new NotImplementedException();
}
@ -3303,8 +3250,6 @@ namespace OpenSim.Framework
public string StackTrace { get; set; }
private readonly string context;
public bool LogThread { get; set; }
public IWorkItemResult WorkItem { get; set; }
public Thread Thread { get; set; }
public bool Running { get; set; }
public bool Aborted { get; set; }
@ -3342,7 +3287,6 @@ namespace OpenSim.Framework
public void Abort()
{
Aborted = true;
WorkItem.Cancel(true);
}
/// <summary>
@ -3504,11 +3448,6 @@ namespace OpenSim.Framework
case FireAndForgetMethod.QueueUserWorkItem:
ThreadPool.UnsafeQueueUserWorkItem(realCallback, obj);
break;
case FireAndForgetMethod.SmartThreadPool:
if (m_ThreadPool == null)
InitThreadPool(2, 15);
threadInfo.WorkItem = m_ThreadPool.QueueWorkItem(realCallback, obj);
break;
case FireAndForgetMethod.Thread:
Thread thread = new(delegate (object o) { realCallback(o); realCallback = null; });
thread.Start(obj);
@ -3674,41 +3613,6 @@ namespace OpenSim.Framework
*/
}
/// <summary>
/// Get information about the current state of the smart thread pool.
/// </summary>
/// <returns>
/// null if this isn't the pool being used for non-scriptengine threads.
/// </returns>
public static STPInfo GetSmartThreadPoolInfo()
{
if (m_ThreadPool == null)
return null;
return new STPInfo()
{
Name = m_ThreadPool.Name,
IsIdle = m_ThreadPool.IsIdle,
IsShuttingDown = m_ThreadPool.IsShuttingdown,
MaxThreads = m_ThreadPool.MaxThreads,
MinThreads = m_ThreadPool.MinThreads,
InUseThreads = m_ThreadPool.InUseThreads,
ActiveThreads = m_ThreadPool.ActiveThreads,
WaitingCallbacks = m_ThreadPool.WaitingCallbacks,
MaxConcurrentWorkItems = m_ThreadPool.Concurrency
};
}
public static void StopThreadPool()
{
if (m_ThreadPool == null)
return;
SmartThreadPool pool = m_ThreadPool;
m_ThreadPool = null;
try { pool.Shutdown(); } catch { }
}
#endregion FireAndForget Threading Pattern
/// <summary>

View file

@ -25,15 +25,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared;
using Amib.Threading;
using log4net;
using Nini.Config;
using OpenMetaverse;

View file

@ -250,7 +250,6 @@ namespace OpenSim.Server.Base
Watchdog.Enabled = false;
WorkManager.Stop();
RemovePIDFile();
Util.StopThreadPool();
Environment.Exit(0);
}

View file

@ -126,9 +126,6 @@ namespace OpenSim
try { ServicePointManager.DnsRefreshTimeout = dnsTimeout; } catch { }
}
if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
Util.InitThreadPool(stpMinThreads, stpMaxThreads);
m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod);
m_log.InfoFormat("[OPENSIM MAIN] Running GC in {0} mode", GCSettings.IsServerGC ? "server":"workstation");

View file

@ -216,8 +216,6 @@ namespace OpenSim.Server
m_Server?.Shutdown();
Util.StopThreadPool();
Environment.Exit(res);
return 0;

View file

@ -1,14 +0,0 @@
namespace Amib.Threading.Internal
{
internal class CanceledWorkItemsGroup
{
public readonly static CanceledWorkItemsGroup NotCanceledWorkItemsGroup = new();
public CanceledWorkItemsGroup()
{
IsCanceled = false;
}
public bool IsCanceled { get; set; }
}
}

View file

@ -1,68 +0,0 @@
using System;
using System.Runtime.Serialization;
namespace Amib.Threading
{
#region Exceptions
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been canceled
/// </summary>
public sealed partial class WorkItemCancelException : Exception
{
public WorkItemCancelException()
{
}
public WorkItemCancelException(string message)
: base(message)
{
}
public WorkItemCancelException(string message, Exception e)
: base(message, e)
{
}
}
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary>
public sealed partial class WorkItemTimeoutException : Exception
{
public WorkItemTimeoutException()
{
}
public WorkItemTimeoutException(string message)
: base(message)
{
}
public WorkItemTimeoutException(string message, Exception e)
: base(message, e)
{
}
}
/// <summary>
/// Represents an exception in case IWorkItemResult.GetResult has been timed out
/// </summary>
public sealed partial class WorkItemResultException : Exception
{
public WorkItemResultException()
{
}
public WorkItemResultException(string message)
: base(message)
{
}
public WorkItemResultException(string message, Exception e)
: base(message, e)
{
}
}
#endregion
}

View file

@ -1,517 +0,0 @@
using System;
using System.Threading;
namespace Amib.Threading
{
#region Delegates
/// <summary>
/// A delegate that represents the method to run as the work item
/// </summary>
/// <param name="state">A state object for the method to run</param>
public delegate object WorkItemCallback(object state);
/// <summary>
/// A delegate to call after the WorkItemCallback completed
/// </summary>
/// <param name="wir">The work item result object</param>
public delegate void PostExecuteWorkItemCallback(IWorkItemResult wir);
/// <summary>
/// A delegate to call after the WorkItemCallback completed
/// </summary>
/// <param name="wir">The work item result object</param>
public delegate void PostExecuteWorkItemCallback<TResult>(IWorkItemResult<TResult> wir);
/// <summary>
/// A delegate to call when a WorkItemsGroup becomes idle
/// </summary>
/// <param name="workItemsGroup">A reference to the WorkItemsGroup that became idle</param>
public delegate void WorkItemsGroupIdleHandler(IWorkItemsGroup workItemsGroup);
/// <summary>
/// A delegate to call after a thread is created, but before
/// it's first use.
/// </summary>
public delegate void ThreadInitializationHandler();
/// <summary>
/// A delegate to call when a thread is about to exit, after
/// it is no longer belong to the pool.
/// </summary>
public delegate void ThreadTerminationHandler();
#endregion
#region IWorkItemsGroup interface
/// <summary>
/// IWorkItemsGroup interface
/// Created by SmartThreadPool.CreateWorkItemsGroup()
/// </summary>
public interface IWorkItemsGroup
{
/// <summary>
/// Get/Set the name of the WorkItemsGroup
/// </summary>
string Name { get; set; }
int localID { get; set; }
/// <summary>
/// Get/Set the maximum number of workitem that execute cocurrency on the thread pool
/// </summary>
int Concurrency { get; set; }
/// <summary>
/// Get the number of work items waiting in the queue.
/// </summary>
int WaitingCallbacks { get; }
/// <summary>
/// Get an array with all the state objects of the currently running items.
/// The array represents a snap shot and impact performance.
/// </summary>
object[] GetStates();
/// <summary>
/// Get the WorkItemsGroup start information
/// </summary>
WIGStartInfo WIGStartInfo { get; }
/// <summary>
/// Starts to execute work items
/// </summary>
void Start();
/// <summary>
/// Cancel all the work items.
/// Same as Cancel(false)
/// </summary>
void Cancel();
/// <summary>
/// Cancel all work items using thread abortion
/// </summary>
/// <param name="abortExecution">True to stop work items by raising ThreadAbortException</param>
void Cancel(bool abortExecution);
/// <summary>
/// Wait for all work item to complete.
/// </summary>
void WaitForIdle();
/// <summary>
/// Wait for all work item to complete, until timeout expired
/// </summary>
/// <param name="timeout">How long to wait for the work items to complete</param>
/// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
bool WaitForIdle(TimeSpan timeout);
/// <summary>
/// Wait for all work item to complete, until timeout expired
/// </summary>
/// <param name="millisecondsTimeout">How long to wait for the work items to complete in milliseconds</param>
/// <returns>Returns true if work items completed within the timeout, otherwise false.</returns>
bool WaitForIdle(int millisecondsTimeout);
/// <summary>
/// IsIdle is true when there are no work items running or queued.
/// </summary>
bool IsIdle { get; }
/// <summary>
/// This event is fired when all work items are completed.
/// (When IsIdle changes to true)
/// This event only work on WorkItemsGroup. On SmartThreadPool
/// it throws the NotImplementedException.
/// </summary>
event WorkItemsGroupIdleHandler OnIdle;
#region QueueWorkItem
IWorkItemResult QueueWorkItem(WaitCallback callback);
IWorkItemResult QueueWorkItem(WaitCallback callback, object state);
IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WaitCallback callback);
IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WaitCallback callback, object state);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="workItemInfo">Work item info</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback);
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="workItemInfo">Work item information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item result</returns>
IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state);
#endregion
#region QueueWorkItem(Action<...>)
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem(Action action);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult object, but its GetResult() will always return null</returns>
IWorkItemResult QueueWorkItem<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
#endregion
#region QueueWorkItem(Func<...>)
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
/// its GetResult() returns a TResult object</returns>
IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
/// its GetResult() returns a TResult object</returns>
IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
/// its GetResult() returns a TResult object</returns>
IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
/// its GetResult() returns a TResult object</returns>
IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3);
/// <summary>
/// Queue a work item.
/// </summary>
/// <returns>Returns a IWorkItemResult&lt;TResult&gt; object.
/// its GetResult() returns a TResult object</returns>
IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
#endregion
}
#endregion
#region CallToPostExecute enumerator
[Flags]
public enum CallToPostExecute
{
/// <summary>
/// Never call to the PostExecute call back
/// </summary>
Never = 0x00,
/// <summary>
/// Call to the PostExecute only when the work item is cancelled
/// </summary>
WhenWorkItemCanceled = 0x01,
/// <summary>
/// Call to the PostExecute only when the work item is not cancelled
/// </summary>
WhenWorkItemNotCanceled = 0x02,
/// <summary>
/// Always call to the PostExecute
/// </summary>
Always = WhenWorkItemCanceled | WhenWorkItemNotCanceled,
}
#endregion
#region IWorkItemResult interface
/// <summary>
/// The common interface of IWorkItemResult and IWorkItemResult&lt;T&gt;
/// </summary>
public interface IWaitableResult
{
/// <summary>
/// This method intent is for internal use.
/// </summary>
/// <returns></returns>
IWorkItemResult GetWorkItemResult();
/// <summary>
/// This method intent is for internal use.
/// </summary>
/// <returns></returns>
IWorkItemResult<TResult> GetWorkItemResultT<TResult>();
}
/// <summary>
/// IWorkItemResult interface.
/// Created when a WorkItemCallback work item is queued.
/// </summary>
public interface IWorkItemResult : IWorkItemResult<object>
{
}
/// <summary>
/// IWorkItemResult&lt;TResult&gt; interface.
/// Created when a Func&lt;TResult&gt; work item is queued.
/// </summary>
public interface IWorkItemResult<TResult> : IWaitableResult
{
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits.
/// </summary>
/// <returns>The result of the work item</returns>
TResult GetResult();
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
TResult GetResult(
int millisecondsTimeout,
bool exitContext);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
TResult GetResult(
TimeSpan timeout,
bool exitContext);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
TResult GetResult(
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
TResult GetResult(
TimeSpan timeout,
bool exitContext,
WaitHandle cancelWaitHandle);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits.
/// </summary>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <returns>The result of the work item</returns>
TResult GetResult(out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <param name="millisecondsTimeout"></param>
/// <param name="exitContext"></param>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
TResult GetResult(
int millisecondsTimeout,
bool exitContext,
out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout.
/// </summary>
/// <param name="exitContext"></param>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <param name="timeout"></param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
TResult GetResult(
TimeSpan timeout,
bool exitContext,
out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <param name="millisecondsTimeout">Timeout in milliseconds, or -1 for infinite</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the blocking if needed</param>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <returns>The result of the work item</returns>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
TResult GetResult(
int millisecondsTimeout,
bool exitContext,
WaitHandle cancelWaitHandle,
out Exception e);
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits until timeout or until the cancelWaitHandle is signaled.
/// </summary>
/// <returns>The result of the work item</returns>
/// <param name="cancelWaitHandle"></param>
/// <param name="e">Filled with the exception if one was thrown</param>
/// <param name="timeout"></param>
/// <param name="exitContext"></param>
/// On timeout throws WorkItemTimeoutException
/// On cancel throws WorkItemCancelException
TResult GetResult(
TimeSpan timeout,
bool exitContext,
WaitHandle cancelWaitHandle,
out Exception e);
/// <summary>
/// Gets an indication whether the asynchronous operation has completed.
/// </summary>
bool IsCompleted { get; }
/// <summary>
/// Gets an indication whether the asynchronous operation has been canceled.
/// </summary>
bool IsCanceled { get; }
/// <summary>
/// Gets the user-defined object that contains context data
/// for the work item method.
/// </summary>
object State { get; }
/// <summary>
/// Same as Cancel(false).
/// </summary>
bool Cancel();
/// <summary>
/// Cancel the work item execution.
/// If the work item is in the queue then it won't execute
/// If the work item is completed, it will remain completed
/// If the work item is in progress then the user can check the SmartThreadPool.IsWorkItemCanceled
/// property to check if the work item has been cancelled. If the abortExecution is set to true then
/// the Smart Thread Pool will send an AbortException to the running thread to stop the execution
/// of the work item. When an in progress work item is canceled its GetResult will throw WorkItemCancelException.
/// If the work item is already cancelled it will remain cancelled
/// </summary>
/// <param name="abortExecution">When true send an AbortException to the executing thread.</param>
/// <returns>Returns true if the work item was not completed, otherwise false.</returns>
bool Cancel(bool abortExecution);
/// <summary>
/// Return the result, same as GetResult()
/// </summary>
TResult Result { get; }
/// <summary>
/// Returns the exception if occured otherwise returns null.
/// </summary>
object Exception { get; }
}
#endregion
}

View file

@ -1,22 +0,0 @@
namespace Amib.Threading.Internal
{
/// <summary>
/// An internal delegate to call when the WorkItem starts or completes
/// </summary>
internal delegate void WorkItemStateCallback(WorkItem workItem);
internal interface IInternalWorkItemResult
{
event WorkItemStateCallback OnWorkItemStarted;
event WorkItemStateCallback OnWorkItemCompleted;
}
internal interface IInternalWaitableResult
{
/// <summary>
/// This method is intent for internal use.
/// </summary>
IWorkItemResult GetWorkItemResult();
}
}

View file

@ -1,35 +0,0 @@
using System;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Amib.Threading.Internal
{
internal static class STPEventWaitHandle
{
public const int WaitTimeout = Timeout.Infinite;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
return WaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int WaitAny(WaitHandle[] waitHandles)
{
return WaitHandle.WaitAny(waitHandles);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
return WaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool WaitOne(WaitHandle waitHandle, int millisecondsTimeout, bool exitContext)
{
return waitHandle.WaitOne(millisecondsTimeout, exitContext);
}
}
}

View file

@ -1,172 +0,0 @@
using System;
using System.Threading;
namespace Amib.Threading
{
/// <summary>
/// Summary description for STPStartInfo.
/// </summary>
public class STPStartInfo : WIGStartInfo
{
private int _idleTimeout = SmartThreadPool.DefaultIdleTimeout;
private int _minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
private int _maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
private ThreadPriority _threadPriority = SmartThreadPool.DefaultThreadPriority;
private bool _areThreadsBackground = SmartThreadPool.DefaultAreThreadsBackground;
private string _threadPoolName = SmartThreadPool.DefaultThreadPoolName;
private int? _maxStackSize = SmartThreadPool.DefaultMaxStackSize;
private bool _supressflow = false;
public STPStartInfo()
{
_threadPriority = SmartThreadPool.DefaultThreadPriority;
_maxWorkerThreads = SmartThreadPool.DefaultMaxWorkerThreads;
_idleTimeout = SmartThreadPool.DefaultIdleTimeout;
_minWorkerThreads = SmartThreadPool.DefaultMinWorkerThreads;
}
public STPStartInfo(STPStartInfo stpStartInfo)
: base(stpStartInfo)
{
_idleTimeout = stpStartInfo.IdleTimeout;
_minWorkerThreads = stpStartInfo.MinWorkerThreads;
_maxWorkerThreads = stpStartInfo.MaxWorkerThreads;
_threadPriority = stpStartInfo.ThreadPriority;
_threadPoolName = stpStartInfo._threadPoolName;
_areThreadsBackground = stpStartInfo.AreThreadsBackground;
_apartmentState = stpStartInfo._apartmentState;
_supressflow = stpStartInfo._supressflow;
}
/// <summary>
/// Get/Set the idle timeout in milliseconds.
/// If a thread is idle (starved) longer than IdleTimeout then it may quit.
/// </summary>
public virtual int IdleTimeout
{
get { return _idleTimeout; }
set
{
ThrowIfReadOnly();
_idleTimeout = value;
}
}
/// <summary>
/// Get/Set the lower limit of threads in the pool.
/// </summary>
public virtual int MinWorkerThreads
{
get { return _minWorkerThreads; }
set
{
ThrowIfReadOnly();
_minWorkerThreads = value;
}
}
/// <summary>
/// Get/Set the upper limit of threads in the pool.
/// </summary>
public virtual int MaxWorkerThreads
{
get { return _maxWorkerThreads; }
set
{
ThrowIfReadOnly();
_maxWorkerThreads = value;
}
}
/// <summary>
/// Get/Set the scheduling priority of the threads in the pool.
/// The Os handles the scheduling.
/// </summary>
public virtual ThreadPriority ThreadPriority
{
get { return _threadPriority; }
set
{
ThrowIfReadOnly();
_threadPriority = value;
}
}
/// <summary>
/// Get/Set the thread pool name. Threads will get names depending on this.
/// </summary>
public virtual string ThreadPoolName
{
get { return _threadPoolName; }
set
{
ThrowIfReadOnly();
_threadPoolName = value;
}
}
/// <summary>
/// Get/Set backgroundness of thread in thread pool.
/// </summary>
public virtual bool AreThreadsBackground
{
get { return _areThreadsBackground; }
set
{
ThrowIfReadOnly();
_areThreadsBackground = value;
}
}
/// <summary>
/// Get a readonly version of this STPStartInfo.
/// </summary>
/// <returns>Returns a readonly reference to this STPStartInfo</returns>
public new STPStartInfo AsReadOnly()
{
return new STPStartInfo(this) { _readOnly = true };
}
private ApartmentState _apartmentState = SmartThreadPool.DefaultApartmentState;
/// <summary>
/// Get/Set the apartment state of threads in the thread pool
/// </summary>
public ApartmentState ApartmentState
{
get { return _apartmentState; }
set
{
ThrowIfReadOnly();
_apartmentState = value;
}
}
/// <summary>
/// Get/Set the max stack size of threads in the thread pool
/// </summary>
public int? MaxStackSize
{
get { return _maxStackSize; }
set
{
ThrowIfReadOnly();
if (value.HasValue && value.Value < 0)
{
throw new ArgumentOutOfRangeException("value", "Value must be greater than 0.");
}
_maxStackSize = value;
}
}
public bool SuppressFlow
{
get { return _supressflow; }
set
{
ThrowIfReadOnly();
_supressflow = value;
}
}
}
}

View file

@ -1,69 +0,0 @@
using Amib.Threading.Internal;
using System;
using System.Threading;
namespace Amib.Threading
{
public partial class SmartThreadPool
{
#region ThreadEntry class
internal class ThreadEntry
{
/// <summary>
/// The thread creation time
/// The value is stored as UTC value.
/// </summary>
private readonly DateTime _creationTime;
/// <summary>
/// The last time this thread has been running
/// It is updated by IAmAlive() method
/// The value is stored as UTC value.
/// </summary>
private DateTime _lastAliveTime;
/// <summary>
/// A reference from each thread in the thread pool to its SmartThreadPool
/// object container.
/// With this variable a thread can know whatever it belongs to a
/// SmartThreadPool.
/// </summary>
private SmartThreadPool _associatedSmartThreadPool;
/// <summary>
/// A reference to the current work item a thread from the thread pool
/// is executing.
/// </summary>
public WorkItem CurrentWorkItem { get; set; }
public Thread WorkThread;
public ThreadEntry(SmartThreadPool stp, Thread th)
{
_associatedSmartThreadPool = stp;
_creationTime = DateTime.UtcNow;
_lastAliveTime = DateTime.MinValue;
WorkThread = th;
}
public SmartThreadPool AssociatedSmartThreadPool
{
get { return _associatedSmartThreadPool; }
}
public void IAmAlive()
{
_lastAliveTime = DateTime.UtcNow;
}
public void Clean()
{
WorkThread = null;
_associatedSmartThreadPool = null;
}
}
#endregion
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AssemblyTitle>Amib.Threading</AssemblyTitle>
<Product>Amib.Threading</Product>
<!-- <Description>Smart Thread Pool</Description>
<AssemblyVersion>2.2.3.0</AssemblyVersion>
<FileVersion>2.2.3.0</FileVersion> -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="3.0.1" />
</ItemGroup>
</Project>

View file

@ -1,141 +0,0 @@
using System;
namespace Amib.Threading
{
/// <summary>
/// Summary description for WIGStartInfo.
/// </summary>
public class WIGStartInfo
{
private bool _useCallerCallContext;
private bool _disposeOfStateObjects;
private CallToPostExecute _callToPostExecute;
private PostExecuteWorkItemCallback _postExecuteWorkItemCallback;
private bool _startSuspended;
private bool _fillStateWithArgs;
protected bool _readOnly;
public WIGStartInfo()
{
_fillStateWithArgs = SmartThreadPool.DefaultFillStateWithArgs;
_startSuspended = SmartThreadPool.DefaultStartSuspended;
_postExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
_callToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
_disposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
_useCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
}
public WIGStartInfo(WIGStartInfo wigStartInfo)
{
_useCallerCallContext = wigStartInfo.UseCallerCallContext;
_disposeOfStateObjects = wigStartInfo.DisposeOfStateObjects;
_callToPostExecute = wigStartInfo.CallToPostExecute;
_postExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback;
_startSuspended = wigStartInfo.StartSuspended;
_fillStateWithArgs = wigStartInfo.FillStateWithArgs;
}
protected void ThrowIfReadOnly()
{
if (_readOnly)
{
throw new NotSupportedException("This is a readonly instance and set is not supported");
}
}
/// <summary>
/// Get/Set if to use the caller's security context
/// </summary>
public virtual bool UseCallerCallContext
{
get { return _useCallerCallContext; }
set
{
ThrowIfReadOnly();
_useCallerCallContext = value;
}
}
/// <summary>
/// Get/Set if to dispose of the state object of a work item
/// </summary>
public virtual bool DisposeOfStateObjects
{
get { return _disposeOfStateObjects; }
set
{
ThrowIfReadOnly();
_disposeOfStateObjects = value;
}
}
/// <summary>
/// Get/Set the run the post execute options
/// </summary>
public virtual CallToPostExecute CallToPostExecute
{
get { return _callToPostExecute; }
set
{
ThrowIfReadOnly();
_callToPostExecute = value;
}
}
/// <summary>
/// Get/Set the default post execute callback
/// </summary>
public virtual PostExecuteWorkItemCallback PostExecuteWorkItemCallback
{
get { return _postExecuteWorkItemCallback; }
set
{
ThrowIfReadOnly();
_postExecuteWorkItemCallback = value;
}
}
/// <summary>
/// Get/Set if the work items execution should be suspended until the Start()
/// method is called.
/// </summary>
public virtual bool StartSuspended
{
get { return _startSuspended; }
set
{
ThrowIfReadOnly();
_startSuspended = value;
}
}
/// <summary>
/// Get/Set the if QueueWorkItem of Action&lt;...&gt;/Func&lt;...&gt; fill the
/// arguments as an object array into the state of the work item.
/// The arguments can be access later by IWorkItemResult.State.
/// </summary>
public virtual bool FillStateWithArgs
{
get { return _fillStateWithArgs; }
set
{
ThrowIfReadOnly();
_fillStateWithArgs = value;
}
}
/// <summary>
/// Get a readonly version of this WIGStartInfo
/// </summary>
/// <returns>Returns a readonly reference to this WIGStartInfoRO</returns>
public WIGStartInfo AsReadOnly()
{
return new WIGStartInfo(this) { _readOnly = true };
}
}
}

View file

@ -1,180 +0,0 @@
using System;
using System.Threading;
namespace Amib.Threading.Internal
{
public partial class WorkItem
{
#region WorkItemResult class
private class WorkItemResult : IWorkItemResult, IInternalWorkItemResult, IInternalWaitableResult
{
/// <summary>
/// A back reference to the work item
/// </summary>
private readonly WorkItem _workItem;
public WorkItemResult(WorkItem workItem)
{
_workItem = workItem;
}
internal WorkItem GetWorkItem()
{
return _workItem;
}
#region IWorkItemResult Members
public bool IsCompleted
{
get
{
return _workItem.IsCompleted;
}
}
public bool IsCanceled
{
get
{
return _workItem.IsCanceled;
}
}
public object GetResult()
{
return _workItem.GetResult(Timeout.Infinite, true, null);
}
public object GetResult(int millisecondsTimeout, bool exitContext)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, null);
}
public object GetResult(TimeSpan timeout, bool exitContext)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null);
}
public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
}
public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle);
}
public object GetResult(out Exception e)
{
return _workItem.GetResult(Timeout.Infinite, true, null, out e);
}
public object GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, null, out e);
}
public object GetResult(TimeSpan timeout, bool exitContext, out Exception e)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, null, out e);
}
public object GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return _workItem.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
}
public object GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return _workItem.GetResult((int)timeout.TotalMilliseconds, exitContext, cancelWaitHandle, out e);
}
public bool Cancel()
{
return Cancel(false);
}
public bool Cancel(bool abortExecution)
{
return _workItem.Cancel(abortExecution);
}
public object State
{
get
{
return _workItem.m_state;
}
}
/// <summary>
/// Return the result, same as GetResult()
/// </summary>
public object Result
{
get { return GetResult(); }
}
/// <summary>
/// Returns the exception if occured otherwise returns null.
/// This value is valid only after the work item completed,
/// before that it is always null.
/// </summary>
public object Exception
{
get { return _workItem.m_exception; }
}
#endregion
#region IInternalWorkItemResult Members
public event WorkItemStateCallback OnWorkItemStarted
{
add
{
_workItem.OnWorkItemStarted += value;
}
remove
{
_workItem.OnWorkItemStarted -= value;
}
}
public event WorkItemStateCallback OnWorkItemCompleted
{
add
{
_workItem.OnWorkItemCompleted += value;
}
remove
{
_workItem.OnWorkItemCompleted -= value;
}
}
#endregion
#region IInternalWorkItemResult Members
public IWorkItemResult GetWorkItemResult()
{
return this;
}
public IWorkItemResult<TResult> GetWorkItemResultT<TResult>()
{
return new WorkItemResultTWrapper<TResult>(this);
}
#endregion
}
#endregion
}
}

View file

@ -1,974 +0,0 @@
using System;
using System.Diagnostics;
using System.Threading;
namespace Amib.Threading.Internal
{
/// <summary>
/// Holds a callback delegate and the state for that delegate.
/// </summary>
public partial class WorkItem
{
#region WorkItemState enum
/// <summary>
/// Indicates the state of the work item in the thread pool
/// </summary>
private enum WorkItemState
{
InQueue = 0, // Nexts: InProgress, Canceled
InProgress = 1, // Nexts: Completed, Canceled
Completed = 2, // Stays Completed
Canceled = 3, // Stays Canceled
}
private static bool IsValidStatesTransition(WorkItemState currentState, WorkItemState nextState)
{
bool valid = false;
switch (currentState)
{
case WorkItemState.InQueue:
valid = (WorkItemState.InProgress == nextState) || (WorkItemState.Canceled == nextState);
break;
case WorkItemState.InProgress:
valid = (WorkItemState.Completed == nextState) || (WorkItemState.Canceled == nextState);
break;
case WorkItemState.Completed:
case WorkItemState.Canceled:
// Cannot be changed
break;
default:
// Unknown state
Debug.Assert(false);
break;
}
return valid;
}
#endregion
#region Fields
/// <summary>
/// Callback delegate for the callback.
/// </summary>
private WorkItemCallback m_callback;
private WaitCallback m_callbackNoResult;
/// <summary>
/// State with which to call the callback delegate.
/// </summary>
private object m_state;
/// <summary>
/// Stores the caller's context
/// </summary>
private ExecutionContext m_callerContext = null;
/// <summary>
/// Holds the result of the mehtod
/// </summary>
private object m_result;
/// <summary>
/// Hold the exception if the method threw it
/// </summary>
private Exception m_exception;
/// <summary>
/// Hold the state of the work item
/// </summary>
private WorkItemState m_workItemState;
/// <summary>
/// A ManualResetEvent to indicate that the result is ready
/// </summary>
private ManualResetEvent m_workItemCompleted;
/// <summary>
/// A reference count to the _workItemCompleted.
/// When it reaches to zero _workItemCompleted is Closed
/// </summary>
private int m_workItemCompletedRefCount;
/// <summary>
/// Represents the result state of the work item
/// </summary>
private readonly WorkItemResult m_workItemResult;
/// <summary>
/// Work item info
/// </summary>
private readonly WorkItemInfo m_workItemInfo;
/// <summary>
/// Called when the WorkItem starts
/// </summary>
private event WorkItemStateCallback m_workItemStartedEvent;
/// <summary>
/// Called when the WorkItem completes
/// </summary>
private event WorkItemStateCallback m_workItemCompletedEvent;
/// <summary>
/// A reference to an object that indicates whatever the
/// WorkItemsGroup has been canceled
/// </summary>
private CanceledWorkItemsGroup m_canceledWorkItemsGroup = CanceledWorkItemsGroup.NotCanceledWorkItemsGroup;
/// <summary>
/// A reference to an object that indicates whatever the
/// SmartThreadPool has been canceled
/// </summary>
private CanceledWorkItemsGroup m_canceledSmartThreadPool = CanceledWorkItemsGroup.NotCanceledWorkItemsGroup;
/// <summary>
/// The work item group this work item belong to.
/// </summary>
private readonly IWorkItemsGroup m_workItemsGroup;
/// <summary>
/// The thread that executes this workitem.
/// This field is available for the period when the work item is executed, before and after it is null.
/// </summary>
private Thread m_executingThread;
/// <summary>
/// The absulote time when the work item will be timeout
/// </summary>
private long m_expirationTime;
#region Performance Counter fields
/// <summary>
/// Stores how long the work item waited on the stp queue
/// </summary>
private Stopwatch _waitingOnQueueStopwatch;
/// <summary>
/// Stores how much time it took the work item to execute after it went out of the queue
/// </summary>
private Stopwatch _processingStopwatch;
#endregion
#endregion
#region Properties
public TimeSpan WaitingTime
{
get
{
return _waitingOnQueueStopwatch.Elapsed;
}
}
public TimeSpan ProcessTime
{
get
{
return _processingStopwatch.Elapsed;
}
}
internal WorkItemInfo WorkItemInfo
{
get
{
return m_workItemInfo;
}
}
#endregion
#region Construction
/// <summary>
/// Initialize the callback holding object.
/// </summary>
/// <param name="workItemsGroup">The workItemGroup of the workitem</param>
/// <param name="workItemInfo">The WorkItemInfo of te workitem</param>
/// <param name="callback">Callback delegate for the callback.</param>
/// <param name="state">State with which to call the callback delegate.</param>
///
/// We assume that the WorkItem object is created within the thread
/// that meant to run the callback
public WorkItem(IWorkItemsGroup workItemsGroup, WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
{
m_workItemsGroup = workItemsGroup;
m_workItemInfo = workItemInfo;
if (m_workItemInfo.UseCallerCallContext && !ExecutionContext.IsFlowSuppressed())
{
ExecutionContext ec = ExecutionContext.Capture();
if (ec is not null)
{
m_callerContext = ec.CreateCopy();
ec.Dispose();
ec = null;
}
}
m_callback = callback;
m_callbackNoResult = null;
m_state = state;
m_workItemResult = new WorkItemResult(this);
Initialize();
}
public WorkItem(IWorkItemsGroup workItemsGroup, WorkItemInfo workItemInfo, WaitCallback callback, object state)
{
m_workItemsGroup = workItemsGroup;
m_workItemInfo = workItemInfo;
if (m_workItemInfo.UseCallerCallContext && !ExecutionContext.IsFlowSuppressed())
{
ExecutionContext ec = ExecutionContext.Capture();
if (ec is not null)
{
m_callerContext = ec.CreateCopy();
ec.Dispose();
ec = null;
}
}
m_callbackNoResult = callback;
m_state = state;
m_workItemResult = new WorkItemResult(this);
Initialize();
}
internal void Initialize()
{
// The _workItemState is changed directly instead of using the SetWorkItemState
// method since we don't want to go throught IsValidStateTransition.
m_workItemState = WorkItemState.InQueue;
m_workItemCompleted = null;
m_workItemCompletedRefCount = 0;
_waitingOnQueueStopwatch = new Stopwatch();
_processingStopwatch = new Stopwatch();
m_expirationTime = m_workItemInfo.Timeout > 0 ? DateTime.UtcNow.Ticks + m_workItemInfo.Timeout * TimeSpan.TicksPerMillisecond : long.MaxValue;
}
internal bool WasQueuedBy(IWorkItemsGroup workItemsGroup)
{
return (workItemsGroup == m_workItemsGroup);
}
#endregion
#region Methods
internal CanceledWorkItemsGroup CanceledWorkItemsGroup
{
get { return m_canceledWorkItemsGroup; }
set { m_canceledWorkItemsGroup = value; }
}
internal CanceledWorkItemsGroup CanceledSmartThreadPool
{
get { return m_canceledSmartThreadPool; }
set { m_canceledSmartThreadPool = value; }
}
/// <summary>
/// Change the state of the work item to in progress if it wasn't canceled.
/// </summary>
/// <returns>
/// Return true on success or false in case the work item was canceled.
/// If the work item needs to run a post execute then the method will return true.
/// </returns>
public bool StartingWorkItem()
{
_waitingOnQueueStopwatch.Stop();
_processingStopwatch.Start();
lock (this)
{
if (IsCanceled)
{
if ((m_workItemInfo.PostExecuteWorkItemCallback is not null) &&
((m_workItemInfo.CallToPostExecute & CallToPostExecute.WhenWorkItemCanceled) == CallToPostExecute.WhenWorkItemCanceled))
{
return true;
}
return false;
}
Debug.Assert(WorkItemState.InQueue == GetWorkItemState());
// No need for a lock yet, only after the state has changed to InProgress
m_executingThread = Thread.CurrentThread;
SetWorkItemState(WorkItemState.InProgress);
}
return true;
}
/// <summary>
/// Execute the work item and the post execute
/// </summary>
public void Execute()
{
CallToPostExecute currentCallToPostExecute = 0;
// Execute the work item if we are in the correct state
switch (GetWorkItemState())
{
case WorkItemState.InProgress:
currentCallToPostExecute |= CallToPostExecute.WhenWorkItemNotCanceled;
ExecuteWorkItem();
break;
case WorkItemState.Canceled:
currentCallToPostExecute |= CallToPostExecute.WhenWorkItemCanceled;
break;
default:
Debug.Assert(false);
throw new NotSupportedException();
}
// Run the post execute as needed
if ((currentCallToPostExecute & m_workItemInfo.CallToPostExecute) != 0)
{
PostExecute();
}
_processingStopwatch.Stop();
}
internal void FireWorkItemCompleted()
{
try
{
m_workItemCompletedEvent?.Invoke(this);
}
catch // Suppress exceptions
{ }
}
internal void FireWorkItemStarted()
{
try
{
m_workItemStartedEvent?.Invoke(this);
}
catch // Suppress exceptions
{ }
}
/// <summary>
/// Execute the work item
/// </summary>
private void ExecuteWorkItem()
{
Exception exception = null;
object result = null;
try
{
try
{
if(m_callbackNoResult is null)
{
if(m_callerContext is null)
result = m_callback(m_state);
else
{
ContextCallback _ccb = new( o => { result =m_callback(o); });
ExecutionContext.Run(m_callerContext, _ccb, m_state);
}
}
else
{
if (m_callerContext is null)
m_callbackNoResult(m_state);
else
{
ContextCallback _ccb = new(o => { m_callbackNoResult(o); });
ExecutionContext.Run(m_callerContext, _ccb, m_state);
}
}
}
catch (Exception e)
{
// Save the exception so we can rethrow it later
exception = e;
}
// Remove the value of the execution thread, so it will be impossible to cancel the work item,
// since it is already completed.
// Cancelling a work item that already completed may cause the abortion of the next work item!!!
Thread executionThread = Interlocked.CompareExchange(ref m_executingThread, null, m_executingThread);
if (executionThread is null)
{
// Oops! we are going to be aborted..., Wait here so we can catch the ThreadAbortException
Thread.Sleep(60 * 1000);
// If after 1 minute this thread was not aborted then let it continue working.
}
}
// We must treat the ThreadAbortException or else it will be stored in the exception variable
catch (ThreadAbortException tae)
{
// Check if the work item was cancelled
// If we got a ThreadAbortException and the STP is not shutting down, it means the
// work items was cancelled.
tae.GetHashCode();
//if (!SmartThreadPool.CurrentThreadEntry.AssociatedSmartThreadPool.IsShuttingdown)
//{
// Thread.ResetAbort();
//}
}
if (!SmartThreadPool.IsWorkItemCanceled)
{
SetResult(result, exception);
}
}
/// <summary>
/// Runs the post execute callback
/// </summary>
private void PostExecute()
{
if (m_workItemInfo.PostExecuteWorkItemCallback is not null)
{
try
{
m_workItemInfo.PostExecuteWorkItemCallback(m_workItemResult);
}
catch (Exception e)
{
Debug.Assert(e is not null);
}
}
}
/// <summary>
/// Set the result of the work item to return
/// </summary>
/// <param name="result">The result of the work item</param>
/// <param name="exception">The exception that was throw while the workitem executed, null
/// if there was no exception.</param>
internal void SetResult(object result, Exception exception)
{
m_result = result;
m_exception = exception;
SignalComplete(false);
}
/// <summary>
/// Returns the work item result
/// </summary>
/// <returns>The work item result</returns>
internal IWorkItemResult GetWorkItemResult()
{
return m_workItemResult;
}
/// <summary>
/// Wait for all work items to complete
/// </summary>
/// <param name="waitableResults">Array of work item result objects</param>
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
/// <returns>
/// true when every work item in waitableResults has completed; otherwise false.
/// </returns>
internal static bool WaitAll( IWaitableResult[] waitableResults, int millisecondsTimeout, bool exitContext,
WaitHandle cancelWaitHandle)
{
if (0 == waitableResults.Length)
{
return true;
}
bool success;
WaitHandle[] waitHandles = new WaitHandle[waitableResults.Length];
GetWaitHandles(waitableResults, waitHandles);
if ((cancelWaitHandle is null) && (waitHandles.Length <= 64))
{
success = STPEventWaitHandle.WaitAll(waitHandles, millisecondsTimeout, exitContext);
}
else
{
success = true;
int millisecondsLeft = millisecondsTimeout;
Stopwatch stopwatch = Stopwatch.StartNew();
WaitHandle[] whs = cancelWaitHandle is null ?
new WaitHandle[] { null } :
new WaitHandle[] { null, cancelWaitHandle };
bool waitInfinitely = (Timeout.Infinite == millisecondsTimeout);
// Iterate over the wait handles and wait for each one to complete.
// We cannot use WaitHandle.WaitAll directly, because the cancelWaitHandle
// won't affect it.
// Each iteration we update the time left for the timeout.
for (int i = 0; i < waitableResults.Length; ++i)
{
// WaitAny don't work with negative numbers
if (!waitInfinitely && (millisecondsLeft < 0))
{
success = false;
break;
}
whs[0] = waitHandles[i];
int result = STPEventWaitHandle.WaitAny(whs, millisecondsLeft, exitContext);
if ((result > 0) || (STPEventWaitHandle.WaitTimeout == result))
{
success = false;
break;
}
if (!waitInfinitely)
{
// Update the time left to wait
millisecondsLeft = millisecondsTimeout - (int)stopwatch.ElapsedMilliseconds;
}
}
}
// Release the wait handles
ReleaseWaitHandles(waitableResults);
return success;
}
/// <summary>
/// Waits for any of the work items in the specified array to complete, cancel, or timeout
/// </summary>
/// <param name="waitableResults">Array of work item result objects</param>
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or Timeout.Infinite (-1) to wait indefinitely.</param>
/// <param name="exitContext">
/// true to exit the synchronization domain for the context before the wait (if in a synchronized context), and reacquire it; otherwise, false.
/// </param>
/// <param name="cancelWaitHandle">A cancel wait handle to interrupt the wait if needed</param>
/// <returns>
/// 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.
/// </returns>
internal static int WaitAny( IWaitableResult[] waitableResults, int millisecondsTimeout,
bool exitContext, WaitHandle cancelWaitHandle)
{
WaitHandle[] waitHandles;
if (cancelWaitHandle is not null)
{
waitHandles = new WaitHandle[waitableResults.Length + 1];
GetWaitHandles(waitableResults, waitHandles);
waitHandles[waitableResults.Length] = cancelWaitHandle;
}
else
{
waitHandles = new WaitHandle[waitableResults.Length];
GetWaitHandles(waitableResults, waitHandles);
}
int result = STPEventWaitHandle.WaitAny(waitHandles, millisecondsTimeout, exitContext);
// Treat cancel as timeout
if (cancelWaitHandle is not null)
{
if (result == waitableResults.Length)
{
result = STPEventWaitHandle.WaitTimeout;
}
}
ReleaseWaitHandles(waitableResults);
return result;
}
/// <summary>
/// Fill an array of wait handles with the work items wait handles.
/// </summary>
/// <param name="waitableResults">An array of work item results</param>
/// <param name="waitHandles">An array of wait handles to fill</param>
private static void GetWaitHandles(IWaitableResult[] waitableResults,
WaitHandle[] waitHandles)
{
for (int i = 0; i < waitableResults.Length; ++i)
{
WorkItemResult wir = waitableResults[i].GetWorkItemResult() as WorkItemResult;
Debug.Assert(wir is not null, "All waitableResults must be WorkItemResult objects");
waitHandles[i] = wir.GetWorkItem().GetWaitHandle();
}
}
/// <summary>
/// Release the work items' wait handles
/// </summary>
/// <param name="waitableResults">An array of work item results</param>
private static void ReleaseWaitHandles(IWaitableResult[] waitableResults)
{
for (int i = 0; i < waitableResults.Length; ++i)
{
WorkItemResult wir = (WorkItemResult)waitableResults[i].GetWorkItemResult();
wir.GetWorkItem().ReleaseWaitHandle();
}
}
#endregion
#region Private Members
private WorkItemState GetWorkItemState()
{
lock (this)
{
if (WorkItemState.Completed == m_workItemState)
{
return m_workItemState;
}
if (WorkItemState.Canceled != m_workItemState && DateTime.UtcNow.Ticks > m_expirationTime)
{
m_workItemState = WorkItemState.Canceled;
return m_workItemState;
}
if(WorkItemState.InProgress != m_workItemState)
{
if (CanceledSmartThreadPool.IsCanceled || CanceledWorkItemsGroup.IsCanceled)
{
return WorkItemState.Canceled;
}
}
return m_workItemState;
}
}
/// <summary>
/// Sets the work item's state
/// </summary>
/// <param name="workItemState">The state to set the work item to</param>
private void SetWorkItemState(WorkItemState workItemState)
{
lock (this)
{
if (IsValidStatesTransition(m_workItemState, workItemState))
{
m_workItemState = workItemState;
}
}
}
/// <summary>
/// Signals that work item has been completed or canceled
/// </summary>
/// <param name="canceled">Indicates that the work item has been canceled</param>
private void SignalComplete(bool canceled)
{
SetWorkItemState(canceled ? WorkItemState.Canceled : WorkItemState.Completed);
lock (this)
{
// If someone is waiting then signal.
m_workItemCompleted?.Set();
}
}
internal void WorkItemIsQueued()
{
_waitingOnQueueStopwatch.Start();
}
#endregion
#region Members exposed by WorkItemResult
/// <summary>
/// Cancel the work item if it didn't start running yet.
/// </summary>
/// <returns>Returns true on success or false if the work item is in progress or already completed</returns>
private bool Cancel(bool abortExecution)
{
bool success = false;
bool signalComplete = false;
lock (this)
{
switch (GetWorkItemState())
{
case WorkItemState.Canceled:
//Debug.WriteLine("Work item already canceled");
if (abortExecution)
{
Thread executionThread = Interlocked.CompareExchange(ref m_executingThread, null, m_executingThread);
if (executionThread is not null)
{
//executionThread.Abort(); // "Cancel"
// No need to signalComplete, because we already cancelled this work item
// so it already signaled its completion.
//signalComplete = true;
}
}
success = true;
break;
case WorkItemState.Completed:
//Debug.WriteLine("Work item cannot be canceled");
break;
case WorkItemState.InProgress:
if (abortExecution)
{
Thread executionThread = Interlocked.CompareExchange(ref m_executingThread, null, m_executingThread);
if (executionThread is not null)
{
//executionThread.Abort(); // "Cancel"
success = true;
signalComplete = true;
}
}
else
{
// **************************
// Stock SmartThreadPool 2.2.3 sets these to true and relies on the thread to check the
// WorkItem cancellation status. However, OpenSimulator uses a different mechanism to notify
// scripts of co-operative termination and the abort code also relies on this method
// returning false in order to implement a small wait.
//
// Therefore, as was the case previously with STP, we will not signal successful cancellation
// here. It's possible that OpenSimulator code could be changed in the future to remove
// the need for this change.
// **************************
success = false;
signalComplete = false;
}
break;
case WorkItemState.InQueue:
// Signal to the wait for completion that the work
// item has been completed (canceled). There is no
// reason to wait for it to get out of the queue
signalComplete = true;
//Debug.WriteLine("Work item canceled");
success = true;
break;
}
if (signalComplete)
{
SignalComplete(true);
}
}
return success;
}
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits for the result, timeout, or cancel.
/// In case of error the method throws and exception
/// </summary>
/// <returns>The result of the work item</returns>
private object GetResult(int millisecondsTimeout, bool exitContext,
WaitHandle cancelWaitHandle)
{
object result = GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out Exception e);
if (e is not null)
{
throw new WorkItemResultException("The work item caused an excpetion, see the inner exception for details", e);
}
return result;
}
/// <summary>
/// Get the result of the work item.
/// If the work item didn't run yet then the caller waits for the result, timeout, or cancel.
/// In case of error the e argument is filled with the exception
/// </summary>
/// <returns>The result of the work item</returns>
private object GetResult( int millisecondsTimeout, bool exitContext,
WaitHandle cancelWaitHandle, out Exception e)
{
e = null;
// Check for cancel
if (WorkItemState.Canceled == GetWorkItemState())
{
throw new WorkItemCancelException("Work item canceled");
}
// Check for completion
if (IsCompleted)
{
e = m_exception;
return m_result;
}
// If no cancelWaitHandle is provided
if (cancelWaitHandle is null)
{
WaitHandle wh = GetWaitHandle();
bool timeout = !STPEventWaitHandle.WaitOne(wh, millisecondsTimeout, exitContext);
ReleaseWaitHandle();
if (timeout)
{
throw new WorkItemTimeoutException("Work item timeout");
}
}
else
{
WaitHandle wh = GetWaitHandle();
int result = STPEventWaitHandle.WaitAny(new WaitHandle[] { wh, cancelWaitHandle });
ReleaseWaitHandle();
switch (result)
{
case 0:
// The work item signaled
// Note that the signal could be also as a result of canceling the
// work item (not the get result)
break;
case 1:
case STPEventWaitHandle.WaitTimeout:
throw new WorkItemTimeoutException("Work item timeout");
default:
Debug.Assert(false);
break;
}
}
// Check for cancel
if (WorkItemState.Canceled == GetWorkItemState())
{
throw new WorkItemCancelException("Work item canceled");
}
Debug.Assert(IsCompleted);
e = m_exception;
// Return the result
return m_result;
}
/// <summary>
/// A wait handle to wait for completion, cancel, or timeout
/// </summary>
private WaitHandle GetWaitHandle()
{
lock (this)
{
if (m_workItemCompleted is null)
{
m_workItemCompleted = new ManualResetEvent(IsCompleted);
}
++m_workItemCompletedRefCount;
}
return m_workItemCompleted;
}
private void ReleaseWaitHandle()
{
lock (this)
{
if (m_workItemCompleted is not null)
{
--m_workItemCompletedRefCount;
if (0 == m_workItemCompletedRefCount)
{
m_workItemCompleted.Close();
m_workItemCompleted = null;
}
}
}
}
/// <summary>
/// Returns true when the work item has completed or canceled
/// </summary>
private bool IsCompleted
{
get
{
lock (this)
{
WorkItemState workItemState = GetWorkItemState();
return ((workItemState == WorkItemState.Completed) ||
(workItemState == WorkItemState.Canceled));
}
}
}
/// <summary>
/// Returns true when the work item has canceled
/// </summary>
public bool IsCanceled
{
get
{
lock (this)
{
return (GetWorkItemState() == WorkItemState.Canceled);
}
}
}
#endregion
internal event WorkItemStateCallback OnWorkItemStarted
{
add
{
m_workItemStartedEvent += value;
}
remove
{
m_workItemStartedEvent -= value;
}
}
internal event WorkItemStateCallback OnWorkItemCompleted
{
add
{
m_workItemCompletedEvent += value;
}
remove
{
m_workItemCompletedEvent -= value;
}
}
public void DisposeOfState()
{
if(m_callerContext is not null)
{
m_callerContext.Dispose();
m_callerContext = null;
}
if(m_workItemCompleted is not null)
{
m_workItemCompleted.Dispose();
m_workItemCompleted = null;
}
if (m_workItemInfo.DisposeOfStateObjects)
{
if (m_state is IDisposable disp)
{
disp.Dispose();
m_state = null;
}
}
m_callback = null;
m_callbackNoResult = null;
}
}
}

View file

@ -1,195 +0,0 @@
using System;
using System.Threading;
using System.Runtime.CompilerServices;
namespace Amib.Threading.Internal
{
#region WorkItemFactory class
public class WorkItemFactory
{
public static WorkItem CreateWorkItem(IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, WorkItemInfo workItemInfo,
WaitCallback callback, object state)
{
ValidateCallback(callback);
ValidateCallback(workItemInfo.PostExecuteWorkItemCallback);
return new WorkItem(workItemsGroup, new WorkItemInfo(workItemInfo), callback, state);
}
public static WorkItem CreateWorkItem(IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo,
WaitCallback callback, object state)
{
ValidateCallback(callback);
WorkItemInfo workItemInfo = new()
{
UseCallerCallContext = wigStartInfo.UseCallerCallContext,
PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback,
CallToPostExecute = wigStartInfo.CallToPostExecute,
DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects,
};
return new WorkItem(workItemsGroup, workItemInfo, callback, state);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, WorkItemCallback callback)
{
return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="workItemInfo">Work item info</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo,
WorkItemInfo workItemInfo, WorkItemCallback callback)
{
return CreateWorkItem(workItemsGroup, wigStartInfo, workItemInfo, callback, null);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The WorkItemsGroup of this workitem</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo,
WorkItemCallback callback, object state)
{
ValidateCallback(callback);
WorkItemInfo workItemInfo = new()
{
UseCallerCallContext = wigStartInfo.UseCallerCallContext,
PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback,
CallToPostExecute = wigStartInfo.CallToPostExecute,
DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects,
};
return new WorkItem( workItemsGroup, workItemInfo, callback, state);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The work items group</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="workItemInfo">Work item information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, WorkItemInfo workItemInfo,
WorkItemCallback callback, object state)
{
ValidateCallback(callback);
ValidateCallback(workItemInfo.PostExecuteWorkItemCallback);
WorkItem workItem = new(
workItemsGroup,
new WorkItemInfo(workItemInfo),
callback,
state);
return workItem;
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The work items group</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <returns>Returns a work item</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WorkItem CreateWorkItem(IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo,
WorkItemCallback callback, object state,PostExecuteWorkItemCallback postExecuteWorkItemCallback)
{
ValidateCallback(callback);
ValidateCallback(postExecuteWorkItemCallback);
WorkItemInfo workItemInfo = new()
{
UseCallerCallContext = wigStartInfo.UseCallerCallContext,
PostExecuteWorkItemCallback = postExecuteWorkItemCallback,
CallToPostExecute = wigStartInfo.CallToPostExecute,
DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects
};
return new WorkItem( workItemsGroup, workItemInfo, callback, state);
}
/// <summary>
/// Create a new work item
/// </summary>
/// <param name="workItemsGroup">The work items group</param>
/// <param name="wigStartInfo">Work item group start information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <returns>Returns a work item</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WorkItem CreateWorkItem(IWorkItemsGroup workItemsGroup,WIGStartInfo wigStartInfo,
WorkItemCallback callback, object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute)
{
ValidateCallback(callback);
ValidateCallback(postExecuteWorkItemCallback);
WorkItemInfo workItemInfo = new()
{
UseCallerCallContext = wigStartInfo.UseCallerCallContext,
PostExecuteWorkItemCallback = postExecuteWorkItemCallback,
CallToPostExecute = callToPostExecute,
DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects
};
return new WorkItem(workItemsGroup, workItemInfo, callback, state);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ValidateCallback(Delegate callback)
{
if (callback is not null && callback.GetInvocationList().Length > 1)
{
throw new NotSupportedException("SmartThreadPool doesn't support delegates chains");
}
}
}
#endregion
}

View file

@ -1,55 +0,0 @@
namespace Amib.Threading
{
#region WorkItemInfo class
/// <summary>
/// Summary description for WorkItemInfo.
/// </summary>
public class WorkItemInfo
{
public WorkItemInfo()
{
UseCallerCallContext = SmartThreadPool.DefaultUseCallerCallContext;
DisposeOfStateObjects = SmartThreadPool.DefaultDisposeOfStateObjects;
CallToPostExecute = SmartThreadPool.DefaultCallToPostExecute;
PostExecuteWorkItemCallback = SmartThreadPool.DefaultPostExecuteWorkItemCallback;
}
public WorkItemInfo(WorkItemInfo workItemInfo)
{
UseCallerCallContext = workItemInfo.UseCallerCallContext;
DisposeOfStateObjects = workItemInfo.DisposeOfStateObjects;
CallToPostExecute = workItemInfo.CallToPostExecute;
PostExecuteWorkItemCallback = workItemInfo.PostExecuteWorkItemCallback;
Timeout = workItemInfo.Timeout;
}
/// <summary>
/// Get/Set if to use the caller's security context
/// </summary>
public bool UseCallerCallContext { get; set; }
/// <summary>
/// Get/Set if to dispose of the state object of a work item
/// </summary>
public bool DisposeOfStateObjects { get; set; }
/// <summary>
/// Get/Set the run the post execute options
/// </summary>
public CallToPostExecute CallToPostExecute { get; set; }
/// <summary>
/// Get/Set the post execute callback
/// </summary>
public PostExecuteWorkItemCallback PostExecuteWorkItemCallback { get; set; }
/// <summary>
/// Get/Set the work item's timout in milliseconds.
/// This is a passive timout. When the timout expires the work item won't be actively aborted!
/// </summary>
public long Timeout { get; set; }
}
#endregion
}

View file

@ -1,123 +0,0 @@
using System;
using System.Threading;
namespace Amib.Threading.Internal
{
#region WorkItemResultTWrapper class
internal class WorkItemResultTWrapper<TResult> : IWorkItemResult<TResult>, IInternalWaitableResult
{
private readonly IWorkItemResult _workItemResult;
public WorkItemResultTWrapper(IWorkItemResult workItemResult)
{
_workItemResult = workItemResult;
}
#region IWorkItemResult<TResult> Members
public TResult GetResult()
{
return (TResult)_workItemResult.GetResult();
}
public TResult GetResult(int millisecondsTimeout, bool exitContext)
{
return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext);
}
public TResult GetResult(TimeSpan timeout, bool exitContext)
{
return (TResult)_workItemResult.GetResult(timeout, exitContext);
}
public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle);
}
public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle)
{
return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle);
}
public TResult GetResult(out Exception e)
{
return (TResult)_workItemResult.GetResult(out e);
}
public TResult GetResult(int millisecondsTimeout, bool exitContext, out Exception e)
{
return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, out e);
}
public TResult GetResult(TimeSpan timeout, bool exitContext, out Exception e)
{
return (TResult)_workItemResult.GetResult(timeout, exitContext, out e);
}
public TResult GetResult(int millisecondsTimeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return (TResult)_workItemResult.GetResult(millisecondsTimeout, exitContext, cancelWaitHandle, out e);
}
public TResult GetResult(TimeSpan timeout, bool exitContext, WaitHandle cancelWaitHandle, out Exception e)
{
return (TResult)_workItemResult.GetResult(timeout, exitContext, cancelWaitHandle, out e);
}
public bool IsCompleted
{
get { return _workItemResult.IsCompleted; }
}
public bool IsCanceled
{
get { return _workItemResult.IsCanceled; }
}
public object State
{
get { return _workItemResult.State; }
}
public bool Cancel()
{
return _workItemResult.Cancel();
}
public bool Cancel(bool abortExecution)
{
return _workItemResult.Cancel(abortExecution);
}
public TResult Result
{
get { return (TResult)_workItemResult.Result; }
}
public object Exception
{
get { return (TResult)_workItemResult.Exception; }
}
#region IInternalWorkItemResult Members
public IWorkItemResult GetWorkItemResult()
{
return _workItemResult.GetWorkItemResult();
}
public IWorkItemResult<TRes> GetWorkItemResultT<TRes>()
{
return (IWorkItemResult<TRes>)this;
}
#endregion
#endregion
}
#endregion
}

View file

@ -1,354 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Diagnostics;
namespace Amib.Threading.Internal
{
#region WorkItemsGroup class
/// <summary>
/// Summary description for WorkItemsGroup.
/// </summary>
public class WorkItemsGroup : WorkItemsGroupBase
{
#region Private members
private readonly object _lock = new();
/// <summary>
/// A reference to the SmartThreadPool instance that created this
/// WorkItemsGroup.
/// </summary>
private readonly SmartThreadPool _stp;
/// <summary>
/// The OnIdle event
/// </summary>
private event WorkItemsGroupIdleHandler _onIdle;
/// <summary>
/// A flag to indicate if the Work Items Group is now suspended.
/// </summary>
private bool _isSuspended;
/// <summary>
/// Defines how many work items of this WorkItemsGroup can run at once.
/// </summary>
private int _concurrency;
/// <summary>
/// Priority queue to hold work items before they are passed
/// to the SmartThreadPool.
/// </summary>
private readonly Queue<WorkItem> _workItemsQueue;
/// <summary>
/// Indicate how many work items are waiting in the SmartThreadPool
/// queue.
/// This value is used to apply the concurrency.
/// </summary>
private int _workItemsInStpQueue;
/// <summary>
/// Indicate how many work items are currently running in the SmartThreadPool.
/// This value is used with the Cancel, to calculate if we can send new
/// work items to the STP.
/// </summary>
private int _workItemsExecutingInStp = 0;
/// <summary>
/// WorkItemsGroup start information
/// </summary>
private readonly WIGStartInfo _workItemsGroupStartInfo;
/// <summary>
/// Signaled when all of the WorkItemsGroup's work item completed.
/// </summary>
private readonly ManualResetEvent _isIdleWaitHandle = new(true);
/// <summary>
/// A common object for all the work items that this work items group
/// generate so we can mark them to cancel in O(1)
/// </summary>
private CanceledWorkItemsGroup _canceledWorkItemsGroup = new();
#endregion
#region Construction
public WorkItemsGroup(SmartThreadPool stp, int concurrency, WIGStartInfo wigStartInfo)
{
if (concurrency <= 0)
{
throw new ArgumentOutOfRangeException(
"concurrency",
concurrency,
"concurrency must be greater than zero");
}
_stp = stp;
_concurrency = concurrency;
_workItemsGroupStartInfo = new WIGStartInfo(wigStartInfo).AsReadOnly();
_workItemsQueue = new Queue<WorkItem>();
Name = "WorkItemsGroup";
// The _workItemsInStpQueue gets the number of currently executing work items,
// because once a work item is executing, it cannot be cancelled.
_workItemsInStpQueue = _workItemsExecutingInStp;
_isSuspended = _workItemsGroupStartInfo.StartSuspended;
}
#endregion
#region WorkItemsGroupBase Overrides
public override int Concurrency
{
get { return _concurrency; }
set
{
Debug.Assert(value > 0);
int diff = value - _concurrency;
_concurrency = value;
if (diff > 0)
{
EnqueueToSTPNextNWorkItem(diff);
}
}
}
public override int WaitingCallbacks
{
get { return _workItemsQueue.Count; }
}
public override object[] GetStates()
{
lock (_lock)
{
object[] states = new object[_workItemsQueue.Count];
int i = 0;
foreach (WorkItem workItem in _workItemsQueue)
{
states[i] = workItem.GetWorkItemResult().State;
++i;
}
return states;
}
}
/// <summary>
/// WorkItemsGroup start information
/// </summary>
public override WIGStartInfo WIGStartInfo
{
get { return _workItemsGroupStartInfo; }
}
/// <summary>
/// Start the Work Items Group if it was started suspended
/// </summary>
public override void Start()
{
// If the Work Items Group already started then quit
if (!_isSuspended)
{
return;
}
_isSuspended = false;
EnqueueToSTPNextNWorkItem(Math.Min(_workItemsQueue.Count, _concurrency));
}
public override void Cancel(bool abortExecution)
{
lock (_lock)
{
_canceledWorkItemsGroup.IsCanceled = true;
_workItemsQueue.Clear();
_workItemsInStpQueue = 0;
_canceledWorkItemsGroup = new CanceledWorkItemsGroup();
}
if (abortExecution)
{
_stp.CancelAbortWorkItemsGroup(this);
}
}
/// <summary>
/// Wait for the thread pool to be idle
/// </summary>
public override bool WaitForIdle(int millisecondsTimeout)
{
SmartThreadPool.ValidateWorkItemsGroupWaitForIdle(this);
return STPEventWaitHandle.WaitOne(_isIdleWaitHandle, millisecondsTimeout, false);
}
public override event WorkItemsGroupIdleHandler OnIdle
{
add { _onIdle += value; }
remove { _onIdle -= value; }
}
#endregion
#region Private methods
private void RegisterToWorkItemCompletion(IWorkItemResult wir)
{
IInternalWorkItemResult iwir = (IInternalWorkItemResult)wir;
iwir.OnWorkItemStarted += OnWorkItemStartedCallback;
iwir.OnWorkItemCompleted += OnWorkItemCompletedCallback;
}
public void OnSTPIsStarting()
{
if (_isSuspended)
{
return;
}
EnqueueToSTPNextNWorkItem(_concurrency);
}
public void EnqueueToSTPNextNWorkItem(int count)
{
for (int i = 0; i < count; ++i)
{
EnqueueToSTPNextWorkItem(null, false);
}
}
private object FireOnIdle(object state)
{
FireOnIdleImpl(_onIdle);
return null;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void FireOnIdleImpl(WorkItemsGroupIdleHandler onIdle)
{
if(onIdle is null)
return;
Delegate[] delegates = onIdle.GetInvocationList();
foreach(WorkItemsGroupIdleHandler eh in delegates)
{
try
{
eh(this);
}
catch { } // Suppress exceptions
}
}
private void OnWorkItemStartedCallback(WorkItem workItem)
{
lock(_lock)
{
++_workItemsExecutingInStp;
}
}
private void OnWorkItemCompletedCallback(WorkItem workItem)
{
EnqueueToSTPNextWorkItem(null, true);
}
internal override void Enqueue(WorkItem workItem)
{
EnqueueToSTPNextWorkItem(workItem);
}
private void EnqueueToSTPNextWorkItem(WorkItem workItem)
{
EnqueueToSTPNextWorkItem(workItem, false);
}
private void EnqueueToSTPNextWorkItem(WorkItem workItem, bool decrementWorkItemsInStpQueue)
{
lock(_lock)
{
// Got here from OnWorkItemCompletedCallback()
if (decrementWorkItemsInStpQueue)
{
--_workItemsInStpQueue;
if(_workItemsInStpQueue < 0)
{
_workItemsInStpQueue = 0;
}
--_workItemsExecutingInStp;
if(_workItemsExecutingInStp < 0)
{
_workItemsExecutingInStp = 0;
}
}
// If the work item is not null then enqueue it
if (workItem is not null)
{
workItem.CanceledWorkItemsGroup = _canceledWorkItemsGroup;
RegisterToWorkItemCompletion(workItem.GetWorkItemResult());
_workItemsQueue.Enqueue(workItem);
//_stp.IncrementWorkItemsCount();
if ((1 == _workItemsQueue.Count) &&
(0 == _workItemsInStpQueue))
{
_stp.RegisterWorkItemsGroup(this);
IsIdle = false;
_isIdleWaitHandle.Reset();
}
}
// If the work items queue of the group is empty than quit
if (0 == _workItemsQueue.Count)
{
if (0 == _workItemsInStpQueue)
{
_stp.UnregisterWorkItemsGroup(this);
IsIdle = true;
_isIdleWaitHandle.Set();
if (decrementWorkItemsInStpQueue && _onIdle is not null && _onIdle.GetInvocationList().Length > 0)
{
_stp.QueueWorkItem(new WorkItemCallback(FireOnIdle));
}
}
return;
}
if (!_isSuspended)
{
if (_workItemsInStpQueue < _concurrency)
{
WorkItem nextWorkItem = _workItemsQueue.Dequeue();
try
{
_stp.Enqueue(nextWorkItem);
}
catch (ObjectDisposedException e)
{
e.GetHashCode();
// The STP has been shutdown
}
++_workItemsInStpQueue;
}
}
}
}
#endregion
}
#endregion
}

View file

@ -1,388 +0,0 @@
using System;
using System.Threading;
namespace Amib.Threading.Internal
{
public abstract class WorkItemsGroupBase : IWorkItemsGroup
{
#region Private Fields
/// <summary>
/// Contains the name of this instance of SmartThreadPool.
/// Can be changed by the user.
/// </summary>
private string _name = "WorkItemsGroupBase";
public WorkItemsGroupBase()
{
IsIdle = true;
}
#endregion
#region IWorkItemsGroup Members
#region Public Methods
/// <summary>
/// Get/Set the name of the SmartThreadPool/WorkItemsGroup instance
/// </summary>
public string Name
{
get { return _name; }
set { _name = value; }
}
public int localID { get; set;}
#endregion
#region Abstract Methods
public abstract int Concurrency { get; set; }
public abstract int WaitingCallbacks { get; }
public abstract object[] GetStates();
public abstract WIGStartInfo WIGStartInfo { get; }
public abstract void Start();
public abstract void Cancel(bool abortExecution);
public abstract bool WaitForIdle(int millisecondsTimeout);
public abstract event WorkItemsGroupIdleHandler OnIdle;
internal abstract void Enqueue(WorkItem workItem);
internal virtual void PreQueueWorkItem() { }
#endregion
#region Common Base Methods
/// <summary>
/// Cancel all the work items.
/// Same as Cancel(false)
/// </summary>
public virtual void Cancel()
{
Cancel(false);
}
/// <summary>
/// Wait for the SmartThreadPool/WorkItemsGroup to be idle
/// </summary>
public void WaitForIdle()
{
WaitForIdle(Timeout.Infinite);
}
/// <summary>
/// Wait for the SmartThreadPool/WorkItemsGroup to be idle
/// </summary>
public bool WaitForIdle(TimeSpan timeout)
{
return WaitForIdle((int)timeout.TotalMilliseconds);
}
/// <summary>
/// IsIdle is true when there are no work items running or queued.
/// </summary>
public bool IsIdle { get; protected set; }
#endregion
#region QueueWorkItem
public IWorkItemResult QueueWorkItem(WaitCallback callback)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, null);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
public IWorkItemResult QueueWorkItem(WaitCallback callback, object state)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WaitCallback callback)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, null);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WaitCallback callback, object state)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemCallback callback)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="workItemInfo">Work item info</param>
/// <param name="callback">A callback to execute</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state)
{
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="workItemInfo">Work item information</param>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
/// <summary>
/// Queue a work item
/// </summary>
/// <param name="callback">A callback to execute</param>
/// <param name="state">
/// The context object of the work item. Used for passing arguments to the work item.
/// </param>
/// <param name="postExecuteWorkItemCallback">
/// A delegate to call after the callback completion
/// </param>
/// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
/// <returns>Returns a work item result</returns>
public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state,
PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute);
Enqueue(workItem);
return workItem.GetWorkItemResult();
}
#endregion
#region QueueWorkItem(Action<...>)
public IWorkItemResult QueueWorkItem (Action action)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this,
WIGStartInfo,
delegate
{
action.Invoke ();
return null;
});
Enqueue (workItem);
return workItem.GetWorkItemResult ();
}
public IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this,
WIGStartInfo,
state =>
{
action.Invoke (arg);
return null;
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null);
Enqueue (workItem);
return workItem.GetWorkItemResult ();
}
public IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this,
WIGStartInfo,
state =>
{
action.Invoke (arg1, arg2);
return null;
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null);
Enqueue (workItem);
return workItem.GetWorkItemResult ();
}
public IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this,
WIGStartInfo,
state =>
{
action.Invoke (arg1, arg2, arg3);
return null;
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null);
Enqueue (workItem);
return workItem.GetWorkItemResult ();
}
public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> (
Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
PreQueueWorkItem ();
WorkItem workItem = WorkItemFactory.CreateWorkItem (
this,
WIGStartInfo,
state =>
{
action.Invoke (arg1, arg2, arg3, arg4);
return null;
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null);
Enqueue (workItem);
return workItem.GetWorkItemResult ();
}
#endregion
#region QueueWorkItem(Func<...>)
public IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(
this,
WIGStartInfo,
state =>
{
return func.Invoke();
});
Enqueue(workItem);
return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
}
public IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(
this,
WIGStartInfo,
state =>
{
return func.Invoke(arg);
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null);
Enqueue(workItem);
return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
}
public IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(
this,
WIGStartInfo,
state =>
{
return func.Invoke(arg1, arg2);
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null);
Enqueue(workItem);
return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
}
public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>(
Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(
this,
WIGStartInfo,
state =>
{
return func.Invoke(arg1, arg2, arg3);
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null);
Enqueue(workItem);
return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
}
public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>(
Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
PreQueueWorkItem();
WorkItem workItem = WorkItemFactory.CreateWorkItem(
this,
WIGStartInfo,
state =>
{
return func.Invoke(arg1, arg2, arg3, arg4);
},
WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null);
Enqueue(workItem);
return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult());
}
#endregion
#endregion
}
}

View file

@ -1,561 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Runtime.CompilerServices;
namespace Amib.Threading.Internal
{
#region WorkItemsQueue class
/// <summary>
/// WorkItemsQueue class.
/// </summary>
public class WorkItemsQueue : IDisposable
{
#region Member variables
/// <summary>
/// Waiters queue (implemented as stack).
/// </summary>
private readonly WaiterEntry _headWaiterEntry = new();
/// <summary>
/// Waiters count
/// </summary>
private int _waitersCount = 0;
/// <summary>
/// Work items queue
/// </summary>
private readonly Queue<WorkItem> _workItems = new();
/// <summary>
/// Indicate that work items are allowed to be queued
/// </summary>
private bool _isWorkItemsQueueActive = true;
[ThreadStatic]
private static WaiterEntry _waiterEntry;
/// <summary>
/// A flag that indicates if the WorkItemsQueue has been disposed.
/// </summary>
private bool _isDisposed = false;
#endregion
#region Public properties
/// <summary>
/// Returns the current number of work items in the queue
/// </summary>
public int Count
{
get
{
return _workItems.Count;
}
}
/// <summary>
/// Returns the current number of waiters
/// </summary>
public int WaitersCount
{
get
{
return _waitersCount;
}
}
#endregion
#region Public methods
/// <summary>
/// Enqueue a work item to the queue.
/// </summary>
public bool EnqueueWorkItem(WorkItem workItem)
{
// A work item cannot be null, since null is used in the
// WaitForWorkItem() method to indicate timeout or cancel
if (workItem is null)
{
throw new ArgumentNullException("workItem", "workItem cannot be null");
}
// First check if there is a waiter waiting for work item. During
// the check, timed out waiters are ignored. If there is no
// waiter then the work item is queued.
lock (this)
{
ValidateNotDisposed();
if (!_isWorkItemsQueueActive)
return false;
while (_waitersCount > 0)
{
// Dequeue a waiter.
WaiterEntry waiterEntry = PopWaiter();
// Signal the waiter. On success break the loop
if (waiterEntry.Signal(workItem))
return true;
}
// Enqueue the work item
_workItems.Enqueue(workItem);
}
return true;
}
public void CloseThreadWaiter()
{
if(_waiterEntry is not null)
{
_waiterEntry.Close();
_waiterEntry = null;
}
}
/// <summary>
/// Waits for a work item or exits on timeout or cancel
/// </summary>
/// <param name="millisecondsTimeout">Timeout in milliseconds</param>
/// <param name="cancelEvent">Cancel wait handle</param>
/// <returns>Returns true if the resource was granted</returns>
public WorkItem DequeueWorkItem( int millisecondsTimeout, WaitHandle cancelEvent)
{
// This method cause the caller to wait for a work item.
// If there is at least one waiting work item then the
// method returns immidiately with it.
//
// If there are no waiting work items then the caller
// is queued between other waiters for a work item to arrive.
//
// If a work item didn't come within millisecondsTimeout or
// the user canceled the wait by signaling the cancelEvent
// then the method returns null to indicate that the caller
// didn't get a work item.
WaiterEntry waiterEntry;
lock (this)
{
ValidateNotDisposed();
// If there are waiting work items then take one and return.
if (_workItems.Count > 0)
return _workItems.Dequeue();
// No waiting work items ...
// Get the waiter entry for the waiters queue
waiterEntry = GetThreadWaiterEntry();
// Put the waiter with the other waiters
PushWaiter(waiterEntry);
}
// Prepare array of wait handle for the WaitHandle.WaitAny()
WaitHandle[] waitHandles = new WaitHandle[] { waiterEntry.WaitHandle, cancelEvent };
// Wait for an available resource, cancel event, or timeout.
// During the wait we are supposes to exit the synchronization
// domain. (Placing true as the third argument of the WaitAny())
// It just doesn't work, I don't know why, so I have two lock(this)
// statments instead of one.
int index = STPEventWaitHandle.WaitAny( waitHandles, millisecondsTimeout, true);
lock (this)
{
// On timeout update the waiterEntry that it is timed out
if (index != 0)
{
// The Timeout() fails if the waiter has already been signaled
// On timeout remove the waiter from the queue.
// Note that the complexity is O(1).
if (waiterEntry.Timeout())
{
RemoveWaiter(waiterEntry, false);
return null;
}
}
// On success return the work item
WorkItem workItem = waiterEntry.WorkItem;
workItem ??= _workItems.Dequeue();
return workItem;
}
}
/// <summary>
/// Cleanup the work items queue, hence no more work
/// items are allowed to be queue
/// </summary>
private void Cleanup()
{
lock (this)
{
// Deactivate only once
if (!_isWorkItemsQueueActive)
{
return;
}
// Don't queue more work items
_isWorkItemsQueueActive = false;
foreach (WorkItem workItem in _workItems)
{
workItem.DisposeOfState();
}
// Clear the work items that are already queued
_workItems.Clear();
// Note:
// I don't iterate over the queue and dispose of work items's states,
// since if a work item has a state object that is still in use in the
// application then I must not dispose it.
// Tell the waiters that they were timed out.
// It won't signal them to exit, but to ignore their
// next work item.
while (_waitersCount > 0)
{
WaiterEntry waiterEntry = PopWaiter();
waiterEntry.Timeout();
}
}
}
public object[] GetStates()
{
lock (this)
{
object[] states = new object[_workItems.Count];
int i = 0;
foreach (WorkItem workItem in _workItems)
{
states[i] = workItem.GetWorkItemResult().State;
++i;
}
return states;
}
}
#endregion
#region Private methods
/// <summary>
/// Returns the WaiterEntry of the current thread
/// </summary>
/// <returns></returns>
/// In order to avoid creation and destuction of WaiterEntry
/// objects each thread has its own WaiterEntry object.
private static WaiterEntry GetThreadWaiterEntry()
{
if (_waiterEntry is null)
{
_waiterEntry = new WaiterEntry();
}
else
_waiterEntry.Reset();
return _waiterEntry;
}
#region Waiters stack methods
/// <summary>
/// Push a new waiter into the waiter's stack
/// </summary>
/// <param name="newWaiterEntry">A waiter to put in the stack</param>
public void PushWaiter(WaiterEntry newWaiterEntry)
{
// Remove the waiter if it is already in the stack and
// update waiter's count as needed
RemoveWaiter(newWaiterEntry, false);
// If the stack is empty then newWaiterEntry is the new head of the stack
if (_headWaiterEntry._nextWaiterEntry is null)
{
_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
}
// If the stack is not empty then put newWaiterEntry as the new head
// of the stack.
else
{
// Save the old first waiter entry
WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
// Update the links
_headWaiterEntry._nextWaiterEntry = newWaiterEntry;
newWaiterEntry._nextWaiterEntry = oldFirstWaiterEntry;
newWaiterEntry._prevWaiterEntry = _headWaiterEntry;
oldFirstWaiterEntry._prevWaiterEntry = newWaiterEntry;
}
// Increment the number of waiters
++_waitersCount;
}
/// <summary>
/// Pop a waiter from the waiter's stack
/// </summary>
/// <returns>Returns the first waiter in the stack</returns>
private WaiterEntry PopWaiter()
{
// Store the current stack head
WaiterEntry oldFirstWaiterEntry = _headWaiterEntry._nextWaiterEntry;
// Store the new stack head
WaiterEntry newHeadWaiterEntry = oldFirstWaiterEntry._nextWaiterEntry;
// Update the old stack head list links and decrement the number
// waiters.
RemoveWaiter(oldFirstWaiterEntry, true);
// Update the new stack head
_headWaiterEntry._nextWaiterEntry = newHeadWaiterEntry;
if (newHeadWaiterEntry is not null)
{
newHeadWaiterEntry._prevWaiterEntry = _headWaiterEntry;
}
// Return the old stack head
return oldFirstWaiterEntry;
}
/// <summary>
/// Remove a waiter from the stack
/// </summary>
/// <param name="waiterEntry">A waiter entry to remove</param>
/// <param name="popDecrement">If true the waiter count is always decremented</param>
private void RemoveWaiter(WaiterEntry waiterEntry, bool popDecrement)
{
// Store the prev entry in the list
WaiterEntry prevWaiterEntry = waiterEntry._prevWaiterEntry;
waiterEntry._prevWaiterEntry = null;
// Store the next entry in the list
WaiterEntry nextWaiterEntry = waiterEntry._nextWaiterEntry;
waiterEntry._nextWaiterEntry = null;
// popDecrement indicate if we need to decrement the waiters count.
// If we got here from PopWaiter then we must decrement.
// If we got here from PushWaiter then we decrement only if
// the waiter was already in the stack.
// If the waiter entry had a prev link then update it.
// It also means that the waiter is already in the list and we
// need to decrement the waiters count.
if (prevWaiterEntry is not null)
{
prevWaiterEntry._nextWaiterEntry = nextWaiterEntry;
popDecrement = true;
}
// If the waiter entry had a next link then update it.
// It also means that the waiter is already in the list and we
// need to decrement the waiters count.
if (nextWaiterEntry is not null)
{
nextWaiterEntry._prevWaiterEntry = prevWaiterEntry;
popDecrement = true;
}
// Decrement the waiters count if needed
if (popDecrement)
--_waitersCount;
}
#endregion
#endregion
#region WaiterEntry class
// A waiter entry in the _waiters queue.
public sealed class WaiterEntry : IDisposable
{
#region Member variables
/// <summary>
/// Event to signal the waiter that it got the work item.
/// </summary>
private AutoResetEvent _waitHandle = new(false);
/// <summary>
/// Flag to know if this waiter already quited from the queue
/// because of a timeout.
/// </summary>
private bool _isTimedout = false;
/// <summary>
/// Flag to know if the waiter was signaled and got a work item.
/// </summary>
private bool _isSignaled = false;
/// <summary>
/// A work item that passed directly to the waiter withou going
/// through the queue
/// </summary>
private WorkItem _workItem = null;
private bool _isDisposed = false;
// Linked list members
internal WaiterEntry _nextWaiterEntry = null;
internal WaiterEntry _prevWaiterEntry = null;
#endregion
#region Construction
public WaiterEntry()
{
}
#endregion
#region Public methods
public WaitHandle WaitHandle
{
get { return _waitHandle; }
}
public WorkItem WorkItem
{
get
{
return _workItem;
}
}
/// <summary>
/// Signal the waiter that it got a work item.
/// </summary>
/// <returns>Return true on success</returns>
/// The method fails if Timeout() preceded its call
public bool Signal(WorkItem workItem)
{
lock (this)
{
if (_isTimedout)
return false;
_workItem = workItem;
_isSignaled = true;
_waitHandle.Set();
return true;
}
}
/// <summary>
/// Mark the wait entry that it has been timed out
/// </summary>
/// <returns>Return true on success</returns>
/// The method fails if Signal() preceded its call
public bool Timeout()
{
lock (this)
{
// Time out can happen only if the waiter wasn't marked as
// signaled
if (_isSignaled)
return false;
// We don't remove the waiter from the queue, the DequeueWorkItem
// method skips _waiters that were timed out.
_isTimedout = true;
return true;
}
}
/// <summary>
/// Reset the wait entry so it can be used again
/// </summary>
public void Reset()
{
_workItem = null;
_isTimedout = false;
_isSignaled = false;
_waitHandle.Reset();
}
/// <summary>
/// Free resources
/// </summary>
public void Close()
{
_workItem = null;
if (_waitHandle is not null)
{
_waitHandle.Close();
_waitHandle = null;
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
lock (this)
{
if (!_isDisposed)
{
Close();
_isDisposed = true;
}
}
}
#endregion
}
#endregion
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed)
{
_isDisposed = true;
Cleanup();
_headWaiterEntry.Close();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ValidateNotDisposed()
{
if (_isDisposed)
{
throw new ObjectDisposedException(GetType().ToString(), "The SmartThreadPool has been shutdown");
}
}
#endregion
}
#endregion
}

View file

@ -1,26 +0,0 @@
/*
* Copyright (c) Contributors, http://aurora-sim.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the Aurora-Sim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 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.
*/

View file

@ -1,60 +0,0 @@
MICROSOFT PUBLIC LICENSE (Ms-PL)
This license governs use of the accompanying software. If you use the software,
you accept this license. If you do not accept the license, do not use the
software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution"
have the same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the
software.
A "contributor" is any person that distributes its contribution under this
license.
"Licensed patents" are a contributor's patent claims that read directly on its
contribution.
2. Grant of Rights
(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.
(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.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any
contributors' name, logo, or trademarks.
(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.
(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.
(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.
(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.

View file

@ -1,19 +0,0 @@
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. 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.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

View file

@ -1,23 +0,0 @@
/*
* C# / XNA port of Bullet (c) 2011 Mark Neale <xexuxjy@hotmail.com>
* http://code.google.com/p/bullet-xna/
*
* Bullet Continuous Collision Detection and Physics Library
* Copyright (c) 2003-2008 Erwin Coumans http://www.bulletphysics.com/
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. 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.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/

View file

@ -1,17 +0,0 @@
/*
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. 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.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
Free for commercial use, but please mail bullet@erwincoumans.com to report projects, and join the forum at
www.continuousphysics.com/Bullet/phpBB2

View file

@ -1,73 +0,0 @@
Embedded http lister uses some code derived from Gauffin Telecom AB HttpServer
Files: HttpServer_OpenSim.dll
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"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.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"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.
"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).
"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.
"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."
"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.
2. Grant of Copyright License.
Subject 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.
3. Grant of Patent License.
Subject 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.
4. Redistribution.
You 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:
1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
2. You must cause any modified files to carry prominent notices stating that You changed the files; and
3. 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
4. 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.
You 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.
5. Submission of Contributions.
Unless 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.
6. Trademarks.
This 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.
7. Disclaimer of Warranty.
Unless 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.
8. Limitation of Liability.
In 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.
9. Accepting Warranty or Additional Liability.
While 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.

View file

@ -1,19 +0,0 @@
Copyright (c) 2003-2008 Niels Kokholm and Peter Sestoft.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

View file

@ -1,12 +0,0 @@
The 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:
There is no problem with using the code in any way you like, as long as
somewhere you say that that is what you have done (in the source for
example).
And of course we disclaim all responsibility for any resulting
damage...
Best wishes
Malcolm Crowe
[1] http://cis.paisley.ac.uk/crow-ci0/CSTools47.zip
[2] http://cis.paisley.ac.uk/crow-ci0/

View file

@ -1,28 +0,0 @@
Copyright (c) 1999/2000 JJ2000 Partners.
This software module was originally developed by Raphaël Grosbois and
Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
Centre France S.A) in the course of development of the JPEG2000
standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
software module is an implementation of a part of the JPEG 2000
Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
Systems AB and Canon Research Centre France S.A (collectively JJ2000
Partners) agree not to assert against ISO/IEC and users of the JPEG
2000 Standard (Users) any of their rights under the copyright, not
including other intellectual property rights, for this software module
with respect to the usage by ISO/IEC and Users of this software module
or modifications thereof for use in hardware or software products
claiming conformance to the JPEG 2000 Standard. Those intending to use
this software module in hardware or software products are advised that
their use may infringe existing patents. The original developers of
this software module, JJ2000 Partners and ISO/IEC assume no liability
for use of this software module or modifications thereof. No license
or right to this software module is granted for non JPEG 2000 Standard
conforming products. JJ2000 Partners have full right to use this
software module for his/her own purpose, assign or donate this
software module to any third party and to inhibit third parties from
using this software module for non JPEG 2000 Standard conforming
products. This copyright notice must be included in all copies or
derivative works of this software module.

View file

@ -1,16 +0,0 @@
Copyright (c) 2012, Alex Regueiro
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
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.
THIS 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 HOLDER 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.

View file

@ -1,28 +0,0 @@
ConvexDecompositionDotNet
-------------------------
The MIT License
Copyright (c) 2010 Intel Corporation.
All rights reserved.
Based on the convexdecomposition library from
<http://codesuppository.googlecode.com> by John W. Ratcliff and Stan Melax.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -1,23 +0,0 @@
COPYRIGHT AND PERMISSION NOTICE
Second Life(TM) Viewer Artwork. Copyright (C) 2008 Linden Research, Inc.
Linden Research, Inc. ("Linden Lab") licenses the Second Life viewer
artwork and other works in the files distributed with this Notice under
the Creative Commons Attribution-Share Alike 3.0 License, available at
http://creativecommons.org/licenses/by-sa/3.0/legalcode. [^] For the license
summary, see http://creativecommons.org/licenses/by-sa/3.0/.
Notwithstanding the foregoing, all of Linden Lab's trademarks, including
but not limited to the Second Life brand name and Second Life Eye-in-Hand
logo, are subject to our trademark policy at
http://secondlife.com/corporate/trademark/.
If you distribute any copies or adaptations of the Second Life viewer
artwork or any other works in these files, you must include this Notice
and clearly identify any changes made to the original works. Include
this Notice and information where copyright notices are usually included,
for example, after your own copyright notice acknowledging your use of
the Second Life viewer artwork, in a text file distributed with your
program, in your application's About window, or on a credits page for
your work.

View file

@ -1,10 +0,0 @@
Copyright (c) 2008, Andrew Arnott, Scott Hanselman, Jason Alexander, et. al
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 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.
* 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.
THIS 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.

View file

@ -1,29 +0,0 @@
The managed BZIP2 code included in Ionic.BZip2.dll and Ionic.Zip.dll is
modified code, based on the bzip2 code in the Apache commons compress
library.
The original BZip2 was created by Julian Seward, and is licensed under
the BSD license.
The following license applies to the Apache code:
-----------------------------------------------------------------------
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

View file

@ -1,70 +0,0 @@
The following licenses govern use of the accompanying software, the
DotNetZip library ("the software"). If you use the software, you accept
these licenses. If you do not accept the license, do not use the software.
The managed ZLIB code included in Ionic.Zlib.dll and Ionic.Zip.dll is
modified code, based on jzlib.
The following notice applies to jzlib:
-----------------------------------------------------------------------
Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
-----------------------------------------------------------------------
jzlib is based on zlib-1.1.3.
The following notice applies to zlib:
-----------------------------------------------------------------------
Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
The ZLIB software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. 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.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly jloup@gzip.org
Mark Adler madler@alumni.caltech.edu
-----------------------------------------------------------------------

View file

@ -1,33 +0,0 @@
Microsoft Public License (Ms-PL)
This 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.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(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.
(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.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(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.
(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.
(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.
(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.

View file

@ -1,477 +0,0 @@
GlynnTucker.Cache
http://gtcache.sourceforge.net/
The 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.
MOZILLA PUBLIC LICENSE
Version 1.1
---------------
1. Definitions.
1.0.1. "Commercial Use" means distribution or otherwise making the
Covered Code available to a third party.
1.1. "Contributor" means each entity that creates or contributes to
the creation of Modifications.
1.2. "Contributor Version" means the combination of the Original
Code, prior Modifications used by a Contributor, and the Modifications
made by that particular Contributor.
1.3. "Covered Code" means the Original Code or Modifications or the
combination of the Original Code and Modifications, in each case
including portions thereof.
1.4. "Electronic Distribution Mechanism" means a mechanism generally
accepted in the software development community for the electronic
transfer of data.
1.5. "Executable" means Covered Code in any form other than Source
Code.
1.6. "Initial Developer" means the individual or entity identified
as the Initial Developer in the Source Code notice required by Exhibit
A.
1.7. "Larger Work" means a work which combines Covered Code or
portions thereof with code not governed by the terms of this License.
1.8. "License" means this document.
1.8.1. "Licensable" means having the right to grant, to the maximum
extent possible, whether at the time of the initial grant or
subsequently acquired, any and all of the rights conveyed herein.
1.9. "Modifications" means any addition to or deletion from the
substance or structure of either the Original Code or any previous
Modifications. When Covered Code is released as a series of files, a
Modification is:
A. Any addition to or deletion from the contents of a file
containing Original Code or previous Modifications.
B. Any new file that contains any part of the Original Code or
previous Modifications.
1.10. "Original Code" means Source Code of computer software code
which is described in the Source Code notice required by Exhibit A as
Original Code, and which, at the time of its release under this
License is not already Covered Code governed by this License.
1.10.1. "Patent Claims" means any patent claim(s), now owned or
hereafter acquired, including without limitation, method, process,
and apparatus claims, in any patent Licensable by grantor.
1.11. "Source Code" means the preferred form of the Covered Code for
making modifications to it, including all modules it contains, plus
any associated interface definition files, scripts used to control
compilation and installation of an Executable, or source code
differential comparisons against either the Original Code or another
well known, available Covered Code of the Contributor's choice. The
Source Code can be in a compressed or archival form, provided the
appropriate decompression or de-archiving software is widely available
for no charge.
1.12. "You" (or "Your") means an individual or a legal entity
exercising rights under, and complying with all of the terms of, this
License or a future version of this License issued under Section 6.1.
For legal entities, "You" includes any entity which controls, is
controlled by, or is under common control with You. For purposes of
this definition, "control" means (a) the power, direct or indirect,
to cause the direction or management of such entity, whether by
contract or otherwise, or (b) ownership of more than fifty percent
(50%) of the outstanding shares or beneficial ownership of such
entity.
2. Source Code License.
2.1. The Initial Developer Grant.
The Initial Developer hereby grants You a world-wide, royalty-free,
non-exclusive license, subject to third party intellectual property
claims:
(a) under intellectual property rights (other than patent or
trademark) Licensable by Initial Developer to use, reproduce,
modify, display, perform, sublicense and distribute the Original
Code (or portions thereof) with or without Modifications, and/or
as part of a Larger Work; and
(b) under Patents Claims infringed by the making, using or
selling of Original Code, to make, have made, use, practice,
sell, and offer for sale, and/or otherwise dispose of the
Original Code (or portions thereof).
(c) the licenses granted in this Section 2.1(a) and (b) are
effective on the date Initial Developer first distributes
Original Code under the terms of this License.
(d) Notwithstanding Section 2.1(b) above, no patent license is
granted: 1) for code that You delete from the Original Code; 2)
separate from the Original Code; or 3) for infringements caused
by: i) the modification of the Original Code or ii) the
combination of the Original Code with other software or devices.
2.2. Contributor Grant.
Subject to third party intellectual property claims, each Contributor
hereby grants You a world-wide, royalty-free, non-exclusive license
(a) under intellectual property rights (other than patent or
trademark) Licensable by Contributor, to use, reproduce, modify,
display, perform, sublicense and distribute the Modifications
created by such Contributor (or portions thereof) either on an
unmodified basis, with other Modifications, as Covered Code
and/or as part of a Larger Work; and
(b) under Patent Claims infringed by the making, using, or
selling of Modifications made by that Contributor either alone
and/or in combination with its Contributor Version (or portions
of such combination), to make, use, sell, offer for sale, have
made, and/or otherwise dispose of: 1) Modifications made by that
Contributor (or portions thereof); and 2) the combination of
Modifications made by that Contributor with its Contributor
Version (or portions of such combination).
(c) the licenses granted in Sections 2.2(a) and 2.2(b) are
effective on the date Contributor first makes Commercial Use of
the Covered Code.
(d) Notwithstanding Section 2.2(b) above, no patent license is
granted: 1) for any code that Contributor has deleted from the
Contributor Version; 2) separate from the Contributor Version;
3) for infringements caused by: i) third party modifications of
Contributor Version or ii) the combination of Modifications made
by that Contributor with other software (except as part of the
Contributor Version) or other devices; or 4) under Patent Claims
infringed by Covered Code in the absence of Modifications made by
that Contributor.
3. Distribution Obligations.
3.1. Application of License.
The Modifications which You create or to which You contribute are
governed by the terms of this License, including without limitation
Section 2.2. The Source Code version of Covered Code may be
distributed only under the terms of this License or a future version
of this License released under Section 6.1, and You must include a
copy of this License with every copy of the Source Code You
distribute. You may not offer or impose any terms on any Source Code
version that alters or restricts the applicable version of this
License or the recipients' rights hereunder. However, You may include
an additional document offering the additional rights described in
Section 3.5.
3.2. Availability of Source Code.
Any Modification which You create or to which You contribute must be
made available in Source Code form under the terms of this License
either on the same media as an Executable version or via an accepted
Electronic Distribution Mechanism to anyone to whom you made an
Executable version available; and if made available via Electronic
Distribution Mechanism, must remain available for at least twelve (12)
months after the date it initially became available, or at least six
(6) months after a subsequent version of that particular Modification
has been made available to such recipients. You are responsible for
ensuring that the Source Code version remains available even if the
Electronic Distribution Mechanism is maintained by a third party.
3.3. Description of Modifications.
You must cause all Covered Code to which You contribute to contain a
file documenting the changes You made to create that Covered Code and
the date of any change. You must include a prominent statement that
the Modification is derived, directly or indirectly, from Original
Code provided by the Initial Developer and including the name of the
Initial Developer in (a) the Source Code, and (b) in any notice in an
Executable version or related documentation in which You describe the
origin or ownership of the Covered Code.
3.4. Intellectual Property Matters
(a) Third Party Claims.
If Contributor has knowledge that a license under a third party's
intellectual property rights is required to exercise the rights
granted by such Contributor under Sections 2.1 or 2.2,
Contributor must include a text file with the Source Code
distribution titled "LEGAL" which describes the claim and the
party making the claim in sufficient detail that a recipient will
know whom to contact. If Contributor obtains such knowledge after
the Modification is made available as described in Section 3.2,
Contributor shall promptly modify the LEGAL file in all copies
Contributor makes available thereafter and shall take other steps
(such as notifying appropriate mailing lists or newsgroups)
reasonably calculated to inform those who received the Covered
Code that new knowledge has been obtained.
(b) Contributor APIs.
If Contributor's Modifications include an application programming
interface and Contributor has knowledge of patent licenses which
are reasonably necessary to implement that API, Contributor must
also include this information in the LEGAL file.
(c) Representations.
Contributor represents that, except as disclosed pursuant to
Section 3.4(a) above, Contributor believes that Contributor's
Modifications are Contributor's original creation(s) and/or
Contributor has sufficient rights to grant the rights conveyed by
this License.
3.5. Required Notices.
You must duplicate the notice in Exhibit A in each file of the Source
Code. If it is not possible to put such notice in a particular Source
Code file due to its structure, then You must include such notice in a
location (such as a relevant directory) where a user would be likely
to look for such a notice. If You created one or more Modification(s)
You may add your name as a Contributor to the notice described in
Exhibit A. You must also duplicate this License in any documentation
for the Source Code where You describe recipients' rights or ownership
rights relating to Covered Code. You may choose to offer, and to
charge a fee for, warranty, support, indemnity or liability
obligations to one or more recipients of Covered Code. However, You
may do so only on Your own behalf, and not on behalf of the Initial
Developer or any Contributor. You must make it absolutely clear than
any such warranty, support, indemnity or liability obligation is
offered by You alone, and You hereby agree to indemnify the Initial
Developer and every Contributor for any liability incurred by the
Initial Developer or such Contributor as a result of warranty,
support, indemnity or liability terms You offer.
3.6. Distribution of Executable Versions.
You may distribute Covered Code in Executable form only if the
requirements of Section 3.1-3.5 have been met for that Covered Code,
and if You include a notice stating that the Source Code version of
the Covered Code is available under the terms of this License,
including a description of how and where You have fulfilled the
obligations of Section 3.2. The notice must be conspicuously included
in any notice in an Executable version, related documentation or
collateral in which You describe recipients' rights relating to the
Covered Code. You may distribute the Executable version of Covered
Code or ownership rights under a license of Your choice, which may
contain terms different from this License, provided that You are in
compliance with the terms of this License and that the license for the
Executable version does not attempt to limit or alter the recipient's
rights in the Source Code version from the rights set forth in this
License. If You distribute the Executable version under a different
license You must make it absolutely clear that any terms which differ
from this License are offered by You alone, not by the Initial
Developer or any Contributor. You hereby agree to indemnify the
Initial Developer and every Contributor for any liability incurred by
the Initial Developer or such Contributor as a result of any such
terms You offer.
3.7. Larger Works.
You may create a Larger Work by combining Covered Code with other code
not governed by the terms of this License and distribute the Larger
Work as a single product. In such a case, You must make sure the
requirements of this License are fulfilled for the Covered Code.
4. Inability to Comply Due to Statute or Regulation.
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Code due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description
must be included in the LEGAL file described in Section 3.4 and must
be included with all distributions of the Source Code. Except to the
extent prohibited by statute or regulation, such description must be
sufficiently detailed for a recipient of ordinary skill to be able to
understand it.
5. Application of this License.
This License applies to code to which the Initial Developer has
attached the notice in Exhibit A and to related Covered Code.
6. Versions of the License.
6.1. New Versions.
Netscape Communications Corporation ("Netscape") may publish revised
and/or new versions of the License from time to time. Each version
will be given a distinguishing version number.
6.2. Effect of New Versions.
Once Covered Code has been published under a particular version of the
License, You may always continue to use it under the terms of that
version. You may also choose to use such Covered Code under the terms
of any subsequent version of the License published by Netscape. No one
other than Netscape has the right to modify the terms applicable to
Covered Code created under this License.
6.3. Derivative Works.
If You create or use a modified version of this License (which you may
only do in order to apply it to code which is not already Covered Code
governed by this License), You must (a) rename Your license so that
the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
"MPL", "NPL" or any confusingly similar phrase do not appear in your
license (except to note that your license differs from this License)
and (b) otherwise make it clear that Your version of the license
contains terms which differ from the Mozilla Public License and
Netscape Public License. (Filling in the name of the Initial
Developer, Original Code or Contributor in the notice described in
Exhibit A shall not of themselves be deemed to be modifications of
this License.)
7. DISCLAIMER OF WARRANTY.
COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
8. TERMINATION.
8.1. This License and the rights granted hereunder will terminate
automatically if You fail to comply with terms herein and fail to cure
such breach within 30 days of becoming aware of the breach. All
sublicenses to the Covered Code which are properly granted shall
survive any termination of this License. Provisions which, by their
nature, must remain in effect beyond the termination of this License
shall survive.
8.2. If You initiate litigation by asserting a patent infringement
claim (excluding declatory judgment actions) against Initial Developer
or a Contributor (the Initial Developer or Contributor against whom
You file such action is referred to as "Participant") alleging that:
(a) such Participant's Contributor Version directly or indirectly
infringes any patent, then any and all rights granted by such
Participant to You under Sections 2.1 and/or 2.2 of this License
shall, upon 60 days notice from Participant terminate prospectively,
unless if within 60 days after receipt of notice You either: (i)
agree in writing to pay Participant a mutually agreeable reasonable
royalty for Your past and future use of Modifications made by such
Participant, or (ii) withdraw Your litigation claim with respect to
the Contributor Version against such Participant. If within 60 days
of notice, a reasonable royalty and payment arrangement are not
mutually agreed upon in writing by the parties or the litigation claim
is not withdrawn, the rights granted by Participant to You under
Sections 2.1 and/or 2.2 automatically terminate at the expiration of
the 60 day notice period specified above.
(b) any software, hardware, or device, other than such Participant's
Contributor Version, directly or indirectly infringes any patent, then
any rights granted to You by such Participant under Sections 2.1(b)
and 2.2(b) are revoked effective as of the date You first made, used,
sold, distributed, or had made, Modifications made by that
Participant.
8.3. If You assert a patent infringement claim against Participant
alleging that such Participant's Contributor Version directly or
indirectly infringes any patent where such claim is resolved (such as
by license or settlement) prior to the initiation of patent
infringement litigation, then the reasonable value of the licenses
granted by such Participant under Sections 2.1 or 2.2 shall be taken
into account in determining the amount or value of any payment or
license.
8.4. In the event of termination under Sections 8.1 or 8.2 above,
all end user license agreements (excluding distributors and resellers)
which have been validly granted by You or any distributor hereunder
prior to termination shall survive termination.
9. LIMITATION OF LIABILITY.
UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
10. U.S. GOVERNMENT END USERS.
The Covered Code is a "commercial item," as that term is defined in
48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
software" and "commercial computer software documentation," as such
terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
all U.S. Government End Users acquire Covered Code with only those
rights set forth herein.
11. MISCELLANEOUS.
This License represents the complete agreement concerning subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. This License shall be governed by
California law provisions (except to the extent applicable law, if
any, provides otherwise), excluding its conflict-of-law provisions.
With respect to disputes in which at least one party is a citizen of,
or an entity chartered or registered to do business in the United
States of America, any litigation relating to this License shall be
subject to the jurisdiction of the Federal Courts of the Northern
District of California, with venue lying in Santa Clara County,
California, with the losing party responsible for costs, including
without limitation, court costs and reasonable attorneys' fees and
expenses. The application of the United Nations Convention on
Contracts for the International Sale of Goods is expressly excluded.
Any law or regulation which provides that the language of a contract
shall be construed against the drafter shall not apply to this
License.
12. RESPONSIBILITY FOR CLAIMS.
As between Initial Developer and the Contributors, each party is
responsible for claims and damages arising, directly or indirectly,
out of its utilization of rights under this License and You agree to
work with Initial Developer and Contributors to distribute such
responsibility on an equitable basis. Nothing herein is intended or
shall be deemed to constitute any admission of liability.
13. MULTIPLE-LICENSED CODE.
Initial Developer may designate portions of the Covered Code as
"Multiple-Licensed". "Multiple-Licensed" means that the Initial
Developer permits you to utilize portions of the Covered Code under
Your choice of the NPL or the alternative licenses, if any, specified
by the Initial Developer in the file described in Exhibit A.
EXHIBIT A -Mozilla Public License.
``The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is ______________________________________.
The Initial Developer of the Original Code is ________________________.
Portions created by ______________________ are Copyright (C) ______
_______________________. All Rights Reserved.
Contributor(s): ______________________________________.
Alternatively, the contents of this file may be used under the terms
of the _____ license (the "[___] License"), in which case the
provisions of [______] License are applicable instead of those
above. If you wish to allow use of your version of this file only
under the terms of the [____] License and not to allow others to use
your version of this file under the MPL, indicate your decision by
deleting the provisions above and replace them with the notice and
other provisions required by the [___] License. If you do not delete
the provisions above, a recipient may use your version of this file
under either the MPL or the [___] License."
[NOTE: The text of this Exhibit A may differ slightly from the text of
the notices in the Source Code files of the Original Code. You should
use the text of this Exhibit A rather than the text found in the
Original Code Source Code for Your Modifications.]

View file

@ -1,31 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * 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.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS 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.

View file

@ -1,17 +0,0 @@
The library is released under the GPL with the following exception:
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent modules,
and to copy and distribute the resulting executable under terms of your
choice, provided that you also meet, for each linked independent module,
the terms and conditions of the license of that module. An independent
module is a module which is not derived from or based on this library.
If you modify this library, you may extend this exception to your
version of the library, but you are not obligated to do so. If you do not
wish to do so, delete this exception statement from your version.

View file

@ -1,15 +0,0 @@
Metaverse Exchange Protocol specification and reference implementation.
Copyright 2008-2009 Bubble Cloud Comminity (http://www.bubblecloud.org)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -1,22 +0,0 @@
MIT License
Copyright © 2006 The Mono.Xna Team
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,41 +0,0 @@
Authors: Lluis Sanchez Gual <lluis@novell.com>
The MIT License
Copyright (C) 2007 Novell, Inc (http://www.novell.com)
Permission is hereby granted, free of charge, to any person obtaining
a copy
of this software and associated documentation files (the "Software"),
to deal
in the Software without restriction, including without limitation
the rights
to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell
copies of the Software, and to permit persons to whom the
Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT.
IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -1,122 +0,0 @@
GPLv2 + MySQL FLOSS License Exception (files COPYING and EXCEPTIONS)
--- file: EXCEPTIONS ---
MySQL FLOSS License Exception
The MySQL AB Exception for Free/Libre and Open Source
Software-only Applications Using MySQL Client Libraries (the
"FLOSS Exception").
Version 0.6, 7 March 2007
Exception Intent
We want specified Free/Libre and Open Source Software (``FLOSS'')
applications to be able to use specified GPL-licensed MySQL client
libraries (the ``Program'') despite the fact that not all FLOSS
licenses are compatible with version 2 of the GNU General Public
License (the ``GPL'').
Legal Terms and Conditions
As a special exception to the terms and conditions of version 2.0
of the GPL:
1. You are free to distribute a Derivative Work that is formed
entirely from the Program and one or more works (each, a
"FLOSS Work") licensed under one or more of the licenses
listed below in section 1, as long as:
a. You obey the GPL in all respects for the Program and the
Derivative Work, except for identifiable sections of the
Derivative Work which are not derived from the Program,
and which can reasonably be considered independent and
separate works in themselves,
b. all identifiable sections of the Derivative Work which
are not derived from the Program, and which can
reasonably be considered independent and separate works
in themselves,
i. are distributed subject to one of the FLOSS licenses
listed below, and
ii. the object code or executable form of those sections
are accompanied by the complete corresponding
machine-readable source code for those sections on
the same medium and under the same FLOSS license as
the corresponding object code or executable forms of
those sections, and
c. any works which are aggregated with the Program or with a
Derivative Work on a volume of a storage or distribution
medium in accordance with the GPL, can reasonably be
considered independent and separate works in themselves
which are not derivatives of either the Program, a
Derivative Work or a FLOSS Work.
If the above conditions are not met, then the Program may only
be copied, modified, distributed or used under the terms and
conditions of the GPL or another valid licensing option from
MySQL AB.
2. FLOSS License List
License name Version(s)/Copyright Date
Academic Free License 2.0
Apache Software License 1.0/1.1/2.0
Apple Public Source License 2.0
Artistic license From Perl 5.8.0
BSD license "July 22 1999"
Common Development and Distribution License (CDDL) 1.0
Common Public License 1.0
Eclipse Public License 1.0
GNU Library or "Lesser" General Public License (LGPL) 2.0/2.1
Jabber Open Source License 1.0
MIT license (As listed in file MIT-License.txt) ---
Mozilla Public License (MPL) 1.0/1.1
Open Software License 2.0
OpenSSL license (with original SSLeay license) "2003" ("1998")
PHP License 3.0
Python license (CNRI Python License) ---
Python Software Foundation License 2.1.1
Sleepycat License "1999"
University of Illinois/NCSA Open Source License ---
W3C License "2001"
X11 License "2001"
Zlib/libpng License ---
Zope Public License 2.0
Due to the many variants of some of the above licenses, we
require that any version follow the 2003 version of the Free
Software Foundation's Free Software Definition
(http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of
the Open Source Definition by the Open Source Initiative
(http://www.opensource.org/docs/definition.php).
3. Definitions
a. Terms used, but not defined, herein shall have the
meaning provided in the GPL.
b. Derivative Work means a derivative work under copyright
law.
4. Applicability: This FLOSS Exception applies to all Programs
that contain a notice placed by MySQL AB saying that the
Program may be distributed under the terms of this FLOSS
Exception. If you create or distribute a work which is a
Derivative Work of both the Program and any other work
licensed under the GPL, then this FLOSS Exception is not
available for that work; thus, you must remove the FLOSS
Exception notice from that work and comply with the GPL in all
respects, including by retaining all GPL notices. You may
choose to redistribute a copy of the Program exclusively under
the terms of the GPL by removing the FLOSS Exception notice
from that copy of the Program, provided that the copy has
never been modified by you or any third party.
Appendix A. Qualified Libraries and Packages
The following is a non-exhaustive list of libraries and packages
which are covered by the FLOSS License Exception. Please note that
this appendix is provided merely as an additional service to
specific FLOSS projects wishing to simplify licensing information
for their users. Compliance with one of the licenses noted under
the "FLOSS license list" section remains a prerequisite.
Package Name Qualifying License and Version
Apache Portable Runtime (APR) Apache Software License 2.0

View file

@ -1,23 +0,0 @@
Nini Configuration Project.
Copyright (c) 2006 Brent R. Matzelle
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -1,7 +0,0 @@
Copyright (c) 2002-2007, The Npgsql Development Team
Permission 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.
IN 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.
THE 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.

View file

@ -1,13 +0,0 @@
Open Dynamics Engine
Copyright (c) 2001-2004, Russell L. Smith.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
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.
Neither 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.
THIS 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.

View file

@ -1,30 +0,0 @@
/*
* Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2007, Professor Benoit Macq
* Copyright (c) 2001-2003, David Janssens
* Copyright (c) 2002-2003, Yannick Verschueren
* Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS 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.
*/

View file

@ -1,21 +0,0 @@
The core Protocol Buffers technology is provided courtesy of Google.
At the time of writing, this is released under the BSD license.
Full details can be found here:
http://code.google.com/p/protobuf/
This .NET implementation is Copyright 2008 Marc Gravell
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -1,16 +0,0 @@
Copyright (c) 2005-2008 Sam Stephenson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,22 +0,0 @@
Microsoft Public License (Ms-PL)
This license governs use of the accompanying software. If you use the software, you
accept this license. If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(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.
(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.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(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.
(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.
(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.
(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.

View file

@ -1,27 +0,0 @@
XML-RPC.NET - XML-RPC for .NET
v2.1.0
Copyright (C) 2001-2006 Charles Cook (chascook@gmail.com)
xmlrpcgen
Copyright (C) 2003 Joe Bork
For more information about XML-RPC.NET visit http://www.xml-rpc.net.
XML-RPC.NET is licensed with MIT X11 license.
(see http://www.xml-rpc.net/faq/xmlrpcnetfaq.html#6.12)
For more information about XML-RPC refer to http://www.xmlrpc.com/
PREQUISITES
-----------
Assembly CookComputing.XmlRpc.dll requires 1.0 .NET runtime and
runs on all later versions.
Assembly CookComputing.XmlRpcV2.dll requires 2.0 .NET runtime.
DOCUMENTATION
-------------
For help on using XML-RPC.NET, see
http://www.xml-rpc.net/faq/xmlrpcnetfaq.html.

View file

@ -1,23 +0,0 @@
Copyright (c) 2006, Second Life Reverse Engineering Team
All rights reserved.
- Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Neither the name of the Second Life Reverse Engineering Team nor the names
of its contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS 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.

View file

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"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.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"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.
"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).
"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.
"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."
"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.
2. Grant of Copyright License. Subject 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.
3. Grant of Patent License. Subject 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.
4. Redistribution. You 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:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) 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
(d) 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.
You 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.
5. Submission of Contributions. Unless 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.
6. Trademarks. This 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.
7. Disclaimer of Warranty. Unless 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.
8. Limitation of Liability. In 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.
9. Accepting Warranty or Additional Liability. While 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.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35303.130
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SmartThreadPool", "ThirdParty\SmartThreadPool\SmartThreadPool.csproj", "{8C618053-0000-0000-0000-000000000000}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{7F5EC7C6-FD99-4084-8530-5D3F28D6D7C0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenSim.Tests.Common", "Tests\OpenSim.Tests.Common\OpenSim.Tests.Common.csproj", "{4B7616BC-6CCE-4B78-AE40-1F24C92442F5}"
@ -155,10 +153,6 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8C618053-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C618053-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C618053-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C618053-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU
{4B7616BC-6CCE-4B78-AE40-1F24C92442F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4B7616BC-6CCE-4B78-AE40-1F24C92442F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4B7616BC-6CCE-4B78-AE40-1F24C92442F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -444,7 +438,6 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8C618053-0000-0000-0000-000000000000} = {E886CEB5-B01D-411F-A7A0-72AA1B71761D}
{4B7616BC-6CCE-4B78-AE40-1F24C92442F5} = {7F5EC7C6-FD99-4084-8530-5D3F28D6D7C0}
{4C8A6BF4-0000-0000-0000-000000000000} = {E886CEB5-B01D-411F-A7A0-72AA1B71761D}
{77DEC20C-0000-0000-0000-000000000000} = {E886CEB5-B01D-411F-A7A0-72AA1B71761D}