Merge branch 'master' into msbuilddll2
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Messaging / CallContext.cs
index a8f218111f26b3acccde060241fd9a35bd838d92..fad4eaf4e4ebffb2cc5f9da6c7d3a4e7e48acd9c 100644 (file)
@@ -42,29 +42,58 @@ namespace System.Runtime.Remoting.Messaging
 {
        
        [Serializable]
+       [System.Runtime.InteropServices.ComVisible (true)]
        public sealed class CallContext 
        {
                [ThreadStatic] static Header [] Headers;
+               [ThreadStatic] static Hashtable logicalDatastore;
                [ThreadStatic] static Hashtable datastore;
+               [ThreadStatic] static object hostContext;
                
                private CallContext ()
                {
                }
 
+               public static object HostContext {
+                       get { return hostContext; }
+                       set { hostContext = value; }
+               }
+
                // public methods
                public static void FreeNamedDataSlot (string name) 
                {
                        Datastore.Remove (name);
+                       LogicalDatastore.Remove (name);
                }
 
                public static object GetData (string name) 
                {
-                       return Datastore [name];
+                       if (LogicalDatastore.ContainsKey (name)) {
+                               return LogicalDatastore [name];
+                       } else {
+                               return Datastore [name];
+                       }
                }
                
                public static void SetData (string name, object data) 
                {
-                       Datastore [name] = data;
+                       if (data is ILogicalThreadAffinative) {
+                               LogicalSetData (name, data);
+                       } else {
+                               LogicalDatastore.Remove (name);
+                               Datastore [name] = data;
+                       }
+               }
+               
+               public static object LogicalGetData (string name) 
+               {
+                       return LogicalDatastore [name];
+               }
+
+               public static void LogicalSetData (string name, object data) 
+               {
+                       Datastore.Remove (name);
+                       LogicalDatastore [name] = data;
                }
 
                public static Header[] GetHeaders () 
@@ -80,12 +109,11 @@ namespace System.Runtime.Remoting.Messaging
                internal static LogicalCallContext CreateLogicalCallContext (bool createEmpty)
                {
                        LogicalCallContext ctx = null;
-                       if (datastore != null) {
-                               foreach (DictionaryEntry entry in datastore)
-                                       if (entry.Value is ILogicalThreadAffinative) {
-                                               if (ctx == null) ctx = new LogicalCallContext ();
-                                               ctx.SetData ((string)entry.Key, entry.Value);
-                                       }
+                       if (logicalDatastore != null) {
+                               ctx = new LogicalCallContext ();
+                               foreach (DictionaryEntry entry in logicalDatastore) {
+                                       ctx.SetData ((string)entry.Key, entry.Value);
+                               }
                        }
 
                        if (ctx == null && createEmpty)
@@ -96,26 +124,31 @@ namespace System.Runtime.Remoting.Messaging
 
                internal static object SetCurrentCallContext (LogicalCallContext ctx)
                {
-                       object oldData = datastore;
+                       object oldData = new object[] { datastore, logicalDatastore };
 
                        if (ctx != null && ctx.HasInfo)
-                               datastore = (Hashtable) ctx.Datastore.Clone ();
+                               logicalDatastore = (Hashtable) ctx.Datastore.Clone ();
                        else
-                               datastore = null;
+                               logicalDatastore = null;
                                
                        return oldData;
                }
                
-               internal static void UpdateCurrentCallContext (LogicalCallContext ctx)
+               internal static void UpdateCurrentLogicalCallContext (LogicalCallContext ctx)
                {
                        Hashtable data = ctx.Datastore;
+                       if (data == null)
+                               return;
+
                        foreach (DictionaryEntry entry in data)
-                               SetData ((string)entry.Key, entry.Value);
+                               LogicalSetData ((string)entry.Key, entry.Value);
                }
                
                internal static void RestoreCallContext (object oldContext)
                {
-                       datastore = (Hashtable) oldContext;
+                       object[] contextArray = (object[])oldContext;
+                       datastore = (Hashtable)contextArray [0];
+                       logicalDatastore = (Hashtable)contextArray [1];
                }
 
                private static Hashtable Datastore
@@ -127,8 +160,19 @@ namespace System.Runtime.Remoting.Messaging
                                return r;
                        }
                }
+
+               private static Hashtable LogicalDatastore
+               {
+                       get {
+                               Hashtable r = logicalDatastore;
+                               if (r == null)
+                                       return logicalDatastore = new Hashtable ();
+                               return r;
+                       }
+               }
        }
 
+       [System.Runtime.InteropServices.ComVisible (true)]
        public interface ILogicalThreadAffinative
        {
        }