aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ThirdParty/SmartThreadPool/CallerThreadContext.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ThirdParty/SmartThreadPool/CallerThreadContext.cs')
-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