using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
+using System.Runtime.Remoting.Messaging;
namespace System.Threading {
-
[Serializable]
public sealed class ExecutionContext : ISerializable
#if NET_4_0
#if !MOONLIGHT
private SecurityContext _sc;
#endif
+ private LogicalCallContext _lcc;
private bool _suppressFlow;
private bool _capture;
{
throw new NotImplementedException ();
}
-
+
public static ExecutionContext Capture ()
+ {
+ return Capture(true);
+ }
+
+ internal static ExecutionContext Capture (bool captureSyncContext)
{
ExecutionContext ec = Thread.CurrentThread.ExecutionContext;
if (ec.FlowSuppressed)
if (SecurityManager.SecurityEnabled)
capture.SecurityContext = SecurityContext.Capture ();
#endif
+ capture.LogicalCallContext = CallContext.CreateLogicalCallContext(false);
return capture;
}
}
// internal stuff
+
+ internal LogicalCallContext LogicalCallContext {
+ get {
+ if (_lcc == null)
+ return new System.Runtime.Remoting.Messaging.LogicalCallContext();
+ return _lcc;
+ }
+ set {
+ _lcc = value;
+ }
+ }
+
#if !MOONLIGHT
internal SecurityContext SecurityContext {
get {
"Null ExecutionContext"));
}
- // FIXME: supporting more than one context (the SecurityContext)
- // will requires a rewrite of this method
-
- SecurityContext.Run (executionContext.SecurityContext, callback, state);
+ // FIXME: supporting more than one context should be done with executionContextSwitcher
+ // and will requires a rewrite of this method
+ var callContextCallBack = new ContextCallback(new Action<object>((ostate) =>
+ {
+ var originalCallContext = CallContext.CreateLogicalCallContext(true);
+ try
+ {
+ CallContext.SetCurrentCallContext(executionContext.LogicalCallContext);
+ callback(ostate);
+ }
+ finally
+ {
+ CallContext.SetCurrentCallContext(originalCallContext);
+ }
+ }));
+ SecurityContext.Run (executionContext.SecurityContext, callContextCallBack, state);
}
public static AsyncFlowControl SuppressFlow ()
}
#endif
}
-}
+}
\ No newline at end of file
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Runtime.Remoting.Messaging;
#if NET_2_0
success = (bool)o;
}
+ public class CallContextValue : ILogicalThreadAffinative
+ {
+ public object Value { get; set; }
+
+ public CallContextValue(object value)
+ {
+ this.Value = value;
+ }
+ }
+
[SetUp]
public void SetUp ()
{
ExecutionContext.RestoreFlow ();
}
+ [Test]
+ public void CaptureCallContext ()
+ {
+ var value = new CallContextValue(true);
+ object capturedValue = null;
+
+ CallContext.SetData("testlc", value);
+
+ ExecutionContext ec = ExecutionContext.Capture ();
+ Assert.IsNotNull (ec, "Capture");
+ Assert.AreEqual(value, CallContext.GetData("testlc"));
+ CallContext.SetData("testlc", null);
+
+ ExecutionContext.Run(ec, new ContextCallback(new Action<object>((data) => {
+ capturedValue = CallContext.GetData("testlc");
+ })), null);
+
+ Assert.AreEqual(value, capturedValue);
+ Assert.AreNotEqual(value, CallContext.GetData("testlc"));
+ }
+
[Test]
public void Capture ()
{