mirror of
https://github.com/opensim/opensim.git
synced 2026-07-20 06:35:39 +08:00
SmartThreadPool code comes from http://www.codeproject.com/Articles/7933/Smart-Thread-Pool This version implements thread abort (via WorkItem.Cancel(true)), threadpool naming, max thread stack, etc. so we no longer need to manually patch those. However, two changes have been made to stock 2.2.3. Major change: WorkItem.Cancel(bool abortExecution) in our version does not succeed if the work item was in progress and thread abort was not specified. This is to match previous behaviour where we handle co-operative termination via another mechanism rather than checking WorkItem.IsCanceled. Minor change: Did not add STP's StopWatch implementation as this is only used WinCE and Silverlight and causes a build clash with System.Diagnostics.StopWatch The reason for updating is to see if this improves http://opensimulator.org/mantis/view.php?id=6557 and http://opensimulator.org/mantis/view.php?id=6586
139 lines
3.7 KiB
C#
139 lines
3.7 KiB
C#
|
|
#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
|
|
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Threading;
|
|
using System.Reflection;
|
|
using System.Web;
|
|
using System.Runtime.Remoting.Messaging;
|
|
|
|
|
|
namespace Amib.Threading.Internal
|
|
{
|
|
#region CallerThreadContext class
|
|
|
|
/// <summary>
|
|
/// This class stores the caller call context in order to restore
|
|
/// it when the work item is executed in the thread pool environment.
|
|
/// </summary>
|
|
internal class CallerThreadContext
|
|
{
|
|
#region Prepare reflection information
|
|
|
|
// Cached type information.
|
|
private static readonly MethodInfo getLogicalCallContextMethodInfo =
|
|
typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
private static readonly MethodInfo setLogicalCallContextMethodInfo =
|
|
typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
private static string HttpContextSlotName = GetHttpContextSlotName();
|
|
|
|
private static string GetHttpContextSlotName()
|
|
{
|
|
FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
|
|
|
|
if (fi != null)
|
|
{
|
|
return (string) fi.GetValue(null);
|
|
}
|
|
|
|
return "HttpContext";
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private fields
|
|
|
|
private HttpContext _httpContext;
|
|
private LogicalCallContext _callContext;
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
private CallerThreadContext()
|
|
{
|
|
}
|
|
|
|
public bool CapturedCallContext
|
|
{
|
|
get
|
|
{
|
|
return (null != _callContext);
|
|
}
|
|
}
|
|
|
|
public bool CapturedHttpContext
|
|
{
|
|
get
|
|
{
|
|
return (null != _httpContext);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Captures the current thread context
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static CallerThreadContext Capture(
|
|
bool captureCallContext,
|
|
bool captureHttpContext)
|
|
{
|
|
Debug.Assert(captureCallContext || captureHttpContext);
|
|
|
|
CallerThreadContext callerThreadContext = new CallerThreadContext();
|
|
|
|
// TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture()
|
|
// Capture Call Context
|
|
if(captureCallContext && (getLogicalCallContextMethodInfo != null))
|
|
{
|
|
callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null);
|
|
if (callerThreadContext._callContext != null)
|
|
{
|
|
callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone();
|
|
}
|
|
}
|
|
|
|
// Capture httpContext
|
|
if (captureHttpContext && (null != HttpContext.Current))
|
|
{
|
|
callerThreadContext._httpContext = HttpContext.Current;
|
|
}
|
|
|
|
return callerThreadContext;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Applies the thread context stored earlier
|
|
/// </summary>
|
|
/// <param name="callerThreadContext"></param>
|
|
public static void Apply(CallerThreadContext callerThreadContext)
|
|
{
|
|
if (null == callerThreadContext)
|
|
{
|
|
throw new ArgumentNullException("callerThreadContext");
|
|
}
|
|
|
|
// Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run()
|
|
// Restore call context
|
|
if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null))
|
|
{
|
|
setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext });
|
|
}
|
|
|
|
// Restore HttpContext
|
|
if (callerThreadContext._httpContext != null)
|
|
{
|
|
HttpContext.Current = callerThreadContext._httpContext;
|
|
//CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
#endif
|