From 1a47ff8094ee414a47aebd310826906d89428a09 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Fri, 30 May 2008 12:27:06 +0000 Subject: * This is Melanie's XEngine script engine. I've not tested this real well, however, it's confirmed to compile and OpenSimulator to run successfully without this script engine active. --- ThirdParty/SmartThreadPool/CallerThreadContext.cs | 223 ++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 ThirdParty/SmartThreadPool/CallerThreadContext.cs (limited to 'ThirdParty/SmartThreadPool/CallerThreadContext.cs') diff --git a/ThirdParty/SmartThreadPool/CallerThreadContext.cs b/ThirdParty/SmartThreadPool/CallerThreadContext.cs new file mode 100644 index 0000000..6ea53f6 --- /dev/null +++ b/ThirdParty/SmartThreadPool/CallerThreadContext.cs @@ -0,0 +1,223 @@ +using System; +using System.Diagnostics; +using System.Threading; +using System.Reflection; +using System.Web; +using System.Runtime.Remoting.Messaging; + + +namespace Amib.Threading +{ + #region CallerThreadContext class + + /// + /// This class stores the caller call context in order to restore + /// it when the work item is executed in the thread pool environment. + /// + internal class CallerThreadContext + { + #region Prepare reflection information + + // Cached type information. + private static MethodInfo getLogicalCallContextMethodInfo = + typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic); + + private static 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); + else // Use the default "HttpContext" slot name + return "HttpContext"; + } + + #endregion + + #region Private fields + + private HttpContext _httpContext = null; + private LogicalCallContext _callContext = null; + + #endregion + + /// + /// Constructor + /// + private CallerThreadContext() + { + } + + public bool CapturedCallContext + { + get + { + return (null != _callContext); + } + } + + public bool CapturedHttpContext + { + get + { + return (null != _httpContext); + } + } + + /// + /// Captures the current thread context + /// + /// + 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; + } + + /// + /// Applies the thread context stored earlier + /// + /// + 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) + { + CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext); + } + } + } + + #endregion + +} + + +/* +// Ami Bar +// amibar@gmail.com + +using System; +using System.Threading; +using System.Globalization; +using System.Security.Principal; +using System.Reflection; +using System.Runtime.Remoting.Contexts; + +namespace Amib.Threading.Internal +{ + #region CallerThreadContext class + + /// + /// This class stores the caller thread context in order to restore + /// it when the work item is executed in the context of the thread + /// from the pool. + /// Note that we can't store the thread's CompressedStack, because + /// it throws a security exception + /// + public class CallerThreadContext + { + private CultureInfo _culture = null; + private CultureInfo _cultureUI = null; + private IPrincipal _principal; + private System.Runtime.Remoting.Contexts.Context _context; + + private static FieldInfo _fieldInfo = GetFieldInfo(); + + private static FieldInfo GetFieldInfo() + { + Type threadType = typeof(Thread); + return threadType.GetField( + "m_Context", + BindingFlags.Instance | BindingFlags.NonPublic); + } + + /// + /// Constructor + /// + private CallerThreadContext() + { + } + + /// + /// Captures the current thread context + /// + /// + public static CallerThreadContext Capture() + { + CallerThreadContext callerThreadContext = new CallerThreadContext(); + + Thread thread = Thread.CurrentThread; + callerThreadContext._culture = thread.CurrentCulture; + callerThreadContext._cultureUI = thread.CurrentUICulture; + callerThreadContext._principal = Thread.CurrentPrincipal; + callerThreadContext._context = Thread.CurrentContext; + return callerThreadContext; + } + + /// + /// Applies the thread context stored earlier + /// + /// + public static void Apply(CallerThreadContext callerThreadContext) + { + Thread thread = Thread.CurrentThread; + thread.CurrentCulture = callerThreadContext._culture; + thread.CurrentUICulture = callerThreadContext._cultureUI; + Thread.CurrentPrincipal = callerThreadContext._principal; + + // Uncomment the following block to enable the Thread.CurrentThread +/* + if (null != _fieldInfo) + { + _fieldInfo.SetValue( + Thread.CurrentThread, + callerThreadContext._context); + } +* / + } + } + + #endregion +} +*/ + -- cgit v1.1