From 206fb306a7820cf593570e35ddfa8e7c5a10e449 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 1 May 2013 19:01:43 +0100
Subject: Update SmartThreadPool to latest version 2.2.3 with a major and minor
change.
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
---
ThirdParty/SmartThreadPool/CallerThreadContext.cs | 361 +++++++++-------------
1 file changed, 138 insertions(+), 223 deletions(-)
(limited to 'ThirdParty/SmartThreadPool/CallerThreadContext.cs')
diff --git a/ThirdParty/SmartThreadPool/CallerThreadContext.cs b/ThirdParty/SmartThreadPool/CallerThreadContext.cs
index 6ea53f6..2177241 100644
--- a/ThirdParty/SmartThreadPool/CallerThreadContext.cs
+++ b/ThirdParty/SmartThreadPool/CallerThreadContext.cs
@@ -1,223 +1,138 @@
-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
-}
-*/
-
+
+#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
+
+ ///
+ /// 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 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
+
+ ///
+ /// 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)
+ {
+ HttpContext.Current = callerThreadContext._httpContext;
+ //CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
+ }
+ }
+ }
+
+ #endregion
+}
+#endif
--
cgit v1.1