aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ThirdParty/SmartThreadPool/CallerThreadContext.cs
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-05-01 19:01:43 +0100
committerJustin Clark-Casey (justincc)2013-05-01 19:01:43 +0100
commit206fb306a7820cf593570e35ddfa8e7c5a10e449 (patch)
tree0ef0fdf42ddc0b63224af52b62b0bad42f62e352 /ThirdParty/SmartThreadPool/CallerThreadContext.cs
parentFix CAPS to work like they should - do not send caps to the viewer if they're... (diff)
downloadopensim-SC-206fb306a7820cf593570e35ddfa8e7c5a10e449.zip
opensim-SC-206fb306a7820cf593570e35ddfa8e7c5a10e449.tar.gz
opensim-SC-206fb306a7820cf593570e35ddfa8e7c5a10e449.tar.bz2
opensim-SC-206fb306a7820cf593570e35ddfa8e7c5a10e449.tar.xz
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
Diffstat (limited to '')
-rw-r--r--ThirdParty/SmartThreadPool/CallerThreadContext.cs361
1 files changed, 138 insertions, 223 deletions
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 @@
1using System; 1
2using System.Diagnostics; 2#if !(_WINDOWS_CE) && !(_SILVERLIGHT) && !(WINDOWS_PHONE)
3using System.Threading; 3
4using System.Reflection; 4using System;
5using System.Web; 5using System.Diagnostics;
6using System.Runtime.Remoting.Messaging; 6using System.Threading;
7 7using System.Reflection;
8 8using System.Web;
9namespace Amib.Threading 9using System.Runtime.Remoting.Messaging;
10{ 10
11 #region CallerThreadContext class 11
12 12namespace Amib.Threading.Internal
13 /// <summary> 13{
14 /// This class stores the caller call context in order to restore 14#region CallerThreadContext class
15 /// it when the work item is executed in the thread pool environment. 15
16 /// </summary> 16 /// <summary>
17 internal class CallerThreadContext 17 /// This class stores the caller call context in order to restore
18 { 18 /// it when the work item is executed in the thread pool environment.
19 #region Prepare reflection information 19 /// </summary>
20 20 internal class CallerThreadContext
21 // Cached type information. 21 {
22 private static MethodInfo getLogicalCallContextMethodInfo = 22#region Prepare reflection information
23 typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic); 23
24 24 // Cached type information.
25 private static MethodInfo setLogicalCallContextMethodInfo = 25 private static readonly MethodInfo getLogicalCallContextMethodInfo =
26 typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic); 26 typeof(Thread).GetMethod("GetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
27 27
28 private static string HttpContextSlotName = GetHttpContextSlotName(); 28 private static readonly MethodInfo setLogicalCallContextMethodInfo =
29 29 typeof(Thread).GetMethod("SetLogicalCallContext", BindingFlags.Instance | BindingFlags.NonPublic);
30 private static string GetHttpContextSlotName() 30
31 { 31 private static string HttpContextSlotName = GetHttpContextSlotName();
32 FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic); 32
33 33 private static string GetHttpContextSlotName()
34 if( fi != null ) 34 {
35 return (string)fi.GetValue(null); 35 FieldInfo fi = typeof(HttpContext).GetField("CallContextSlotName", BindingFlags.Static | BindingFlags.NonPublic);
36 else // Use the default "HttpContext" slot name 36
37 return "HttpContext"; 37 if (fi != null)
38 } 38 {
39 39 return (string) fi.GetValue(null);
40 #endregion 40 }
41 41
42 #region Private fields 42 return "HttpContext";
43 43 }
44 private HttpContext _httpContext = null; 44
45 private LogicalCallContext _callContext = null; 45 #endregion
46 46
47 #endregion 47#region Private fields
48 48
49 /// <summary> 49 private HttpContext _httpContext;
50 /// Constructor 50 private LogicalCallContext _callContext;
51 /// </summary> 51
52 private CallerThreadContext() 52 #endregion
53 { 53
54 } 54 /// <summary>
55 55 /// Constructor
56 public bool CapturedCallContext 56 /// </summary>
57 { 57 private CallerThreadContext()
58 get 58 {
59 { 59 }
60 return (null != _callContext); 60
61 } 61 public bool CapturedCallContext
62 } 62 {
63 63 get
64 public bool CapturedHttpContext 64 {
65 { 65 return (null != _callContext);
66 get 66 }
67 { 67 }
68 return (null != _httpContext); 68
69 } 69 public bool CapturedHttpContext
70 } 70 {
71 71 get
72 /// <summary> 72 {
73 /// Captures the current thread context 73 return (null != _httpContext);
74 /// </summary> 74 }
75 /// <returns></returns> 75 }
76 public static CallerThreadContext Capture( 76
77 bool captureCallContext, 77 /// <summary>
78 bool captureHttpContext) 78 /// Captures the current thread context
79 { 79 /// </summary>
80 Debug.Assert(captureCallContext || captureHttpContext); 80 /// <returns></returns>
81 81 public static CallerThreadContext Capture(
82 CallerThreadContext callerThreadContext = new CallerThreadContext(); 82 bool captureCallContext,
83 83 bool captureHttpContext)
84 // TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture() 84 {
85 // Capture Call Context 85 Debug.Assert(captureCallContext || captureHttpContext);
86 if(captureCallContext && (getLogicalCallContextMethodInfo != null)) 86
87 { 87 CallerThreadContext callerThreadContext = new CallerThreadContext();
88 callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null); 88
89 if (callerThreadContext._callContext != null) 89 // TODO: In NET 2.0, redo using the new feature of ExecutionContext class - Capture()
90 { 90 // Capture Call Context
91 callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone(); 91 if(captureCallContext && (getLogicalCallContextMethodInfo != null))
92 } 92 {
93 } 93 callerThreadContext._callContext = (LogicalCallContext)getLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, null);
94 94 if (callerThreadContext._callContext != null)
95 // Capture httpContext 95 {
96 if (captureHttpContext && (null != HttpContext.Current)) 96 callerThreadContext._callContext = (LogicalCallContext)callerThreadContext._callContext.Clone();
97 { 97 }
98 callerThreadContext._httpContext = HttpContext.Current; 98 }
99 } 99
100 100 // Capture httpContext
101 return callerThreadContext; 101 if (captureHttpContext && (null != HttpContext.Current))
102 } 102 {
103 103 callerThreadContext._httpContext = HttpContext.Current;
104 /// <summary> 104 }
105 /// Applies the thread context stored earlier 105
106 /// </summary> 106 return callerThreadContext;
107 /// <param name="callerThreadContext"></param> 107 }
108 public static void Apply(CallerThreadContext callerThreadContext) 108
109 { 109 /// <summary>
110 if (null == callerThreadContext) 110 /// Applies the thread context stored earlier
111 { 111 /// </summary>
112 throw new ArgumentNullException("callerThreadContext"); 112 /// <param name="callerThreadContext"></param>
113 } 113 public static void Apply(CallerThreadContext callerThreadContext)
114 114 {
115 // Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run() 115 if (null == callerThreadContext)
116 // Restore call context 116 {
117 if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null)) 117 throw new ArgumentNullException("callerThreadContext");
118 { 118 }
119 setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext }); 119
120 } 120 // Todo: In NET 2.0, redo using the new feature of ExecutionContext class - Run()
121 121 // Restore call context
122 // Restore HttpContext 122 if ((callerThreadContext._callContext != null) && (setLogicalCallContextMethodInfo != null))
123 if (callerThreadContext._httpContext != null) 123 {
124 { 124 setLogicalCallContextMethodInfo.Invoke(Thread.CurrentThread, new object[] { callerThreadContext._callContext });
125 CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext); 125 }
126 } 126
127 } 127 // Restore HttpContext
128 } 128 if (callerThreadContext._httpContext != null)
129 129 {
130 #endregion 130 HttpContext.Current = callerThreadContext._httpContext;
131 131 //CallContext.SetData(HttpContextSlotName, callerThreadContext._httpContext);
132} 132 }
133 133 }
134 134 }
135/* 135
136// Ami Bar 136 #endregion
137// amibar@gmail.com 137}
138 138#endif
139using System;
140using System.Threading;
141using System.Globalization;
142using System.Security.Principal;
143using System.Reflection;
144using System.Runtime.Remoting.Contexts;
145
146namespace Amib.Threading.Internal
147{
148 #region CallerThreadContext class
149
150 /// <summary>
151 /// This class stores the caller thread context in order to restore
152 /// it when the work item is executed in the context of the thread
153 /// from the pool.
154 /// Note that we can't store the thread's CompressedStack, because
155 /// it throws a security exception
156 /// </summary>
157 public class CallerThreadContext
158 {
159 private CultureInfo _culture = null;
160 private CultureInfo _cultureUI = null;
161 private IPrincipal _principal;
162 private System.Runtime.Remoting.Contexts.Context _context;
163
164 private static FieldInfo _fieldInfo = GetFieldInfo();
165
166 private static FieldInfo GetFieldInfo()
167 {
168 Type threadType = typeof(Thread);
169 return threadType.GetField(
170 "m_Context",
171 BindingFlags.Instance | BindingFlags.NonPublic);
172 }
173
174 /// <summary>
175 /// Constructor
176 /// </summary>
177 private CallerThreadContext()
178 {
179 }
180
181 /// <summary>
182 /// Captures the current thread context
183 /// </summary>
184 /// <returns></returns>
185 public static CallerThreadContext Capture()
186 {
187 CallerThreadContext callerThreadContext = new CallerThreadContext();
188
189 Thread thread = Thread.CurrentThread;
190 callerThreadContext._culture = thread.CurrentCulture;
191 callerThreadContext._cultureUI = thread.CurrentUICulture;
192 callerThreadContext._principal = Thread.CurrentPrincipal;
193 callerThreadContext._context = Thread.CurrentContext;
194 return callerThreadContext;
195 }
196
197 /// <summary>
198 /// Applies the thread context stored earlier
199 /// </summary>
200 /// <param name="callerThreadContext"></param>
201 public static void Apply(CallerThreadContext callerThreadContext)
202 {
203 Thread thread = Thread.CurrentThread;
204 thread.CurrentCulture = callerThreadContext._culture;
205 thread.CurrentUICulture = callerThreadContext._cultureUI;
206 Thread.CurrentPrincipal = callerThreadContext._principal;
207
208 // Uncomment the following block to enable the Thread.CurrentThread
209/*
210 if (null != _fieldInfo)
211 {
212 _fieldInfo.SetValue(
213 Thread.CurrentThread,
214 callerThreadContext._context);
215 }
216* /
217 }
218 }
219
220 #endregion
221}
222*/
223