2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Messaging / CallContext.cs
index 56c136667a5136ce47d091463d8e6ca0bac33a8d..a8f218111f26b3acccde060241fd9a35bd838d92 100644 (file)
 ///This class is sealed.
 ///</summary>
 
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// 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;
 using System.Threading;
 using System.Collections;
@@ -21,6 +44,13 @@ namespace System.Runtime.Remoting.Messaging
        [Serializable]
        public sealed class CallContext 
        {
+               [ThreadStatic] static Header [] Headers;
+               [ThreadStatic] static Hashtable datastore;
+               
+               private CallContext ()
+               {
+               }
+
                // public methods
                public static void FreeNamedDataSlot (string name) 
                {
@@ -31,62 +61,70 @@ namespace System.Runtime.Remoting.Messaging
                {
                        return Datastore [name];
                }
-
-               public static Header[] GetHeaders () 
-               {
-                       return (Header[]) Datastore ["__Headers"];
-               }
-
+               
                public static void SetData (string name, object data) 
                {
                        Datastore [name] = data;
                }
 
+               public static Header[] GetHeaders () 
+               {
+                       return Headers;
+               }
+               
                public static void SetHeaders (Header[] headers) 
                {
-                       Datastore ["__Headers"] = headers;
+                       Headers = headers;
                }
 
-               internal static LogicalCallContext CreateLogicalCallContext ()
+               internal static LogicalCallContext CreateLogicalCallContext (bool createEmpty)
                {
-                       LocalDataStoreSlot ds = Thread.GetNamedDataSlot ("__CallContext");
-                       Hashtable res = (Hashtable) Thread.GetData (ds);
+                       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);
+                                       }
+                       }
 
-                       LogicalCallContext ctx = new LogicalCallContext();
-                       if (res == null) return ctx;
+                       if (ctx == null && createEmpty)
+                               return new LogicalCallContext ();
+                       else
+                               return ctx;
+               }
 
-                       foreach (DictionaryEntry entry in res)
-                               if (entry.Value is ILogicalThreadAffinative)
-                                       ctx.SetData ((string)entry.Key, entry.Value);
+               internal static object SetCurrentCallContext (LogicalCallContext ctx)
+               {
+                       object oldData = datastore;
 
-                       return ctx;
+                       if (ctx != null && ctx.HasInfo)
+                               datastore = (Hashtable) ctx.Datastore.Clone ();
+                       else
+                               datastore = null;
+                               
+                       return oldData;
                }
-
-               internal static void SetCurrentCallContext (LogicalCallContext ctx)
+               
+               internal static void UpdateCurrentCallContext (LogicalCallContext ctx)
                {
                        Hashtable data = ctx.Datastore;
-                       if (data == null) return;
-
                        foreach (DictionaryEntry entry in data)
                                SetData ((string)entry.Key, entry.Value);
                }
-
-               internal static void ResetCurrentCallContext ()
+               
+               internal static void RestoreCallContext (object oldContext)
                {
-                       LocalDataStoreSlot ds = Thread.GetNamedDataSlot ("__CallContext");
-                       Thread.SetData (ds, null);
+                       datastore = (Hashtable) oldContext;
                }
 
                private static Hashtable Datastore
                {
                        get {
-                               LocalDataStoreSlot ds = Thread.GetNamedDataSlot ("__CallContext");
-                               Hashtable res = (Hashtable) Thread.GetData (ds);
-                               if (res == null) {
-                                       res = new Hashtable ();
-                                       Thread.SetData (ds, res);
-                               }
-                               return res;
+                               Hashtable r = datastore;
+                               if (r == null)
+                                       return datastore = new Hashtable ();
+                               return r;
                        }
                }
        }