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