// // System.Runtime.Remoting.Messaging.CallContext.cs // // Author: Jaime Anguiano Olarra (jaime@gnome.org) // Lluis Sanchez Gual (lluis@ximian.com) // // (c) 2002, Jaime Anguiano Olarra // /// ///Provides several properties that come with the execution code path. ///This class is sealed. /// // // 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; namespace System.Runtime.Remoting.Messaging { [Serializable] public sealed class CallContext { internal const string HeadersKey = "__Headers"; internal const string ContextKey = "__CallContext"; private CallContext () { } // public methods public static void FreeNamedDataSlot (string name) { Datastore.Remove (name); } public static object GetData (string name) { return Datastore [name]; } public static Header[] GetHeaders () { return (Header[]) Datastore [HeadersKey]; } public static void SetData (string name, object data) { Datastore [name] = data; } public static void SetHeaders (Header[] headers) { Datastore [HeadersKey] = headers; } internal static LogicalCallContext CreateLogicalCallContext () { LocalDataStoreSlot ds = Thread.GetNamedDataSlot (ContextKey); Hashtable res = (Hashtable) Thread.GetData (ds); LogicalCallContext ctx = new LogicalCallContext(); if (res == null) return ctx; foreach (DictionaryEntry entry in res) if (entry.Value is ILogicalThreadAffinative) ctx.SetData ((string)entry.Key, entry.Value); return ctx; } internal static object SetCurrentCallContext (LogicalCallContext ctx) { LocalDataStoreSlot ds = Thread.GetNamedDataSlot (ContextKey); object oldData = Thread.GetData (ds); if (ctx != null && ctx.HasInfo) { Hashtable newData = new Hashtable(); Hashtable data = ctx.Datastore; foreach (DictionaryEntry entry in data) newData [(string)entry.Key] = entry.Value; Thread.SetData (ds, newData); } else Thread.SetData (ds, null); return oldData; } internal static void UpdateCurrentCallContext (LogicalCallContext ctx) { Hashtable data = ctx.Datastore; foreach (DictionaryEntry entry in data) SetData ((string)entry.Key, entry.Value); } internal static void RestoreCallContext (object oldContext) { LocalDataStoreSlot ds = Thread.GetNamedDataSlot (ContextKey); Thread.SetData (ds, oldContext); } private static Hashtable Datastore { get { LocalDataStoreSlot ds = Thread.GetNamedDataSlot (ContextKey); Hashtable res = (Hashtable) Thread.GetData (ds); if (res == null) { res = new Hashtable (); Thread.SetData (ds, res); } return res; } } } public interface ILogicalThreadAffinative { } }