16 internal const int CTX_DEFAULT_CONTEXT = 1;
18 internal const int CTX_FROZEN = 2;
20 internal const int CTX_THREADPOOL_AWARE = 4;
22 private const int GROW_BY = 8;
24 private const int STATICS_BUCKET_SIZE = 8;
28 private DynamicPropertyHolder _dphCtx;
30 private volatile LocalDataStoreHolder _localDataStore;
38 private object[] _ctxStatics;
40 private IntPtr _internalContext;
44 private int _ctxFlags;
46 private int _numCtxProps;
48 private int _ctxStaticsCurrentBucket;
50 private int _ctxStaticsFreeIndex;
52 private static DynamicPropertyHolder _dphGlobal =
new DynamicPropertyHolder();
54 private static LocalDataStoreMgr _localDataStoreMgr =
new LocalDataStoreMgr();
56 private static int _ctxIDCounter = 0;
69 internal virtual IntPtr InternalContextID => _internalContext;
73 internal bool IsDefaultContext => _ctxID == 0;
86 internal virtual bool IsThreadPoolAware => (_ctxFlags & 4) == 4;
95 if (_ctxProps ==
null)
102 Array.
Copy(_ctxProps, array, _numCtxProps);
108 private LocalDataStore MyLocalStore
112 if (_localDataStore ==
null)
114 lock (_localDataStoreMgr)
116 if (_localDataStore ==
null)
118 _localDataStore = _localDataStoreMgr.CreateLocalDataStore();
122 return _localDataStore.Store;
126 internal virtual IDynamicProperty[] PerContextDynamicProperties
134 return _dphCtx.DynamicProperties;
138 internal static ArrayWithSize GlobalDynamicSinks
143 return _dphGlobal.DynamicSinks;
147 internal virtual ArrayWithSize DynamicSinks
156 return _dphCtx.DynamicSinks;
171 if ((_ctxFlags & 1) != 0)
179 DomainSpecificRemotingData remotingData =
Thread.
GetDomain().RemotingData;
180 if (remotingData !=
null)
182 IContextProperty[] appDomainContextProperties = remotingData.AppDomainContextProperties;
183 if (appDomainContextProperties !=
null)
185 for (
int i = 0; i < appDomainContextProperties.Length; i++)
191 if ((_ctxFlags & 1) != 0)
195 SetupInternalContext((_ctxFlags & 1) == 1);
200 private extern void SetupInternalContext(
bool bDefault);
203 [SecuritySafeCritical]
206 if (_internalContext != IntPtr.Zero && (_ctxFlags & 1) == 0)
208 CleanupInternalContext();
214 private extern void CleanupInternalContext();
217 internal static Context CreateDefaultContext()
228 if (_ctxProps ==
null || name ==
null)
233 for (
int i = 0; i < _numCtxProps; i++)
235 if (_ctxProps[i].Name.Equals(name))
237 result = _ctxProps[i];
252 if (prop ==
null || prop.
Name ==
null)
256 if ((_ctxFlags & 2) != 0)
262 CheckPropertyNameClash(prop.
Name, _ctxProps, _numCtxProps);
263 if (_ctxProps ==
null || _numCtxProps == _ctxProps.Length)
265 _ctxProps = GrowPropertiesArray(_ctxProps);
267 _ctxProps[_numCtxProps++] = prop;
272 internal virtual void InternalFreeze()
275 for (
int i = 0; i < _numCtxProps; i++)
277 _ctxProps[i].
Freeze(
this);
288 if ((_ctxFlags & 2) != 0)
296 internal virtual void SetThreadPoolAware()
302 internal static void CheckPropertyNameClash(
string name, IContextProperty[] props,
int count)
309 if (props[num].Name.Equals(name))
318 throw new InvalidOperationException(Environment.GetResourceString(
"InvalidOperation_DuplicatePropertyName"));
321 internal static IContextProperty[] GrowPropertiesArray(IContextProperty[] props)
323 int num = ((props !=
null) ? props.Length : 0) + 8;
324 IContextProperty[] array =
new IContextProperty[num];
327 Array.Copy(props, array, props.Length);
335 if (_serverContextChain ==
null)
337 IMessageSink messageSink = ServerContextTerminatorSink.MessageSink;
339 int num = _numCtxProps;
342 obj = _ctxProps[num];
343 IContributeServerContextSink contributeServerContextSink = obj as IContributeServerContextSink;
344 if (contributeServerContextSink !=
null)
346 messageSink = contributeServerContextSink.GetServerContextSink(messageSink);
347 if (messageSink ==
null)
349 throw new RemotingException(Environment.GetResourceString(
"Remoting_Contexts_BadProperty"));
355 if (_serverContextChain ==
null)
357 _serverContextChain = messageSink;
361 return _serverContextChain;
367 if (_clientContextChain ==
null)
369 IMessageSink messageSink = ClientContextTerminatorSink.MessageSink;
371 for (
int i = 0; i < _numCtxProps; i++)
374 IContributeClientContextSink contributeClientContextSink = obj as IContributeClientContextSink;
375 if (contributeClientContextSink !=
null)
377 messageSink = contributeClientContextSink.GetClientContextSink(messageSink);
378 if (messageSink ==
null)
380 throw new RemotingException(Environment.GetResourceString(
"Remoting_Contexts_BadProperty"));
386 if (_clientContextChain ==
null)
388 _clientContextChain = messageSink;
392 return _clientContextChain;
396 internal virtual IMessageSink CreateServerObjectChain(MarshalByRefObject serverObj)
398 IMessageSink messageSink =
new ServerObjectTerminatorSink(serverObj);
400 int num = _numCtxProps;
403 obj = _ctxProps[num];
404 IContributeObjectSink contributeObjectSink = obj as IContributeObjectSink;
405 if (contributeObjectSink !=
null)
407 messageSink = contributeObjectSink.GetObjectSink(serverObj, messageSink);
408 if (messageSink ==
null)
410 throw new RemotingException(Environment.GetResourceString(
"Remoting_Contexts_BadProperty"));
418 internal virtual IMessageSink CreateEnvoyChain(MarshalByRefObject objectOrProxy)
420 IMessageSink messageSink = EnvoyTerminatorSink.MessageSink;
422 for (
int i = 0; i < _numCtxProps; i++)
425 IContributeEnvoySink contributeEnvoySink = obj as IContributeEnvoySink;
426 if (contributeEnvoySink !=
null)
428 messageSink = contributeEnvoySink.GetEnvoySink(objectOrProxy, messageSink);
429 if (messageSink ==
null)
431 throw new RemotingException(Environment.GetResourceString(
"Remoting_Contexts_BadProperty"));
444 int num = _numCtxProps;
448 obj = _ctxProps[num];
449 IContextPropertyActivator contextPropertyActivator = obj as IContextPropertyActivator;
450 if (contextPropertyActivator !=
null)
453 if (constructionCallMessage !=
null)
457 contextPropertyActivator.CollectFromClientContext(constructionCallMessage);
461 contextPropertyActivator.DeliverClientContextToServerContext(constructionCallMessage);
464 else if (bServerSide)
494 return "ContextID: " + _ctxID;
506 if ((_ctxFlags & 2) == 0)
511 if (currentContext ==
this)
516 currentContext.DoCallBackGeneric(InternalContextID, deleg);
521 internal static void DoCallBackFromEE(
IntPtr targetCtxID,
IntPtr privateData,
int targetDomainID)
523 if (targetDomainID == 0)
525 CallBackHelper @
object =
new CallBackHelper(privateData, bFromEE:
true, targetDomainID);
530 TransitionCall msg =
new TransitionCall(targetCtxID, privateData, targetDomainID);
531 Message.PropagateCallContextFromThreadToMessage(msg);
533 Message.PropagateCallContextFromMessageToThread(message);
535 if (methodReturnMessage ==
null || methodReturnMessage.
Exception ==
null)
545 TransitionCall msg =
new TransitionCall(targetCtxID, deleg);
546 Message.PropagateCallContextFromThreadToMessage(msg);
550 Message.PropagateCallContextFromMessageToThread(message);
553 if (methodReturnMessage !=
null && methodReturnMessage.
Exception !=
null)
561 internal static extern void ExecuteCallBackInEE(IntPtr privateData);
568 return _localDataStoreMgr.AllocateDataSlot();
577 return _localDataStoreMgr.AllocateNamedDataSlot(name);
586 return _localDataStoreMgr.GetNamedDataSlot(name);
594 _localDataStoreMgr.FreeNamedDataSlot(name);
615 private int ReserveSlot()
617 if (_ctxStatics ==
null)
619 _ctxStatics =
new object[8];
620 _ctxStatics[0] =
null;
621 _ctxStaticsFreeIndex = 1;
622 _ctxStaticsCurrentBucket = 0;
624 if (_ctxStaticsFreeIndex == 8)
626 object[] array =
new object[8];
627 object[] array2 = _ctxStatics;
628 while (array2[0] !=
null)
630 array2 = (
object[])array2[0];
633 _ctxStaticsFreeIndex = 1;
634 _ctxStaticsCurrentBucket++;
636 return _ctxStaticsFreeIndex++ | (_ctxStaticsCurrentBucket << 16);
647 [SecuritySafeCritical]
656 if (obj !=
null && ctx !=
null)
662 return IdentityHolder.AddDynamicProperty(obj, prop);
664 return AddDynamicProperty(ctx, prop);
675 [SecuritySafeCritical]
683 if (obj !=
null && ctx !=
null)
690 return IdentityHolder.RemoveDynamicProperty(obj, name);
692 return RemoveDynamicProperty(ctx, name);
698 return ctx?.AddPerContextDynamicProperty(prop) ?? AddGlobalDynamicProperty(prop);
702 private bool AddPerContextDynamicProperty(IDynamicProperty prop)
706 DynamicPropertyHolder dphCtx =
new DynamicPropertyHolder();
715 return _dphCtx.AddDynamicProperty(prop);
719 private static bool AddGlobalDynamicProperty(IDynamicProperty prop)
721 return _dphGlobal.AddDynamicProperty(prop);
725 internal static bool RemoveDynamicProperty(
Context ctx,
string name)
727 return ctx?.RemovePerContextDynamicProperty(name) ?? RemoveGlobalDynamicProperty(name);
731 private bool RemovePerContextDynamicProperty(
string name)
735 throw new RemotingException(
string.Format(
CultureInfo.
CurrentCulture, Environment.GetResourceString(
"Remoting_Contexts_NoProperty"), name));
737 return _dphCtx.RemoveDynamicProperty(name);
741 private static bool RemoveGlobalDynamicProperty(
string name)
743 return _dphGlobal.RemoveDynamicProperty(name);
747 internal virtual bool NotifyDynamicSinks(
IMessage msg,
bool bCliSide,
bool bStart,
bool bAsync,
bool bNotifyGlobals)
750 if (bNotifyGlobals && _dphGlobal.DynamicProperties !=
null)
752 ArrayWithSize globalDynamicSinks = GlobalDynamicSinks;
753 if (globalDynamicSinks !=
null)
755 DynamicPropertyHolder.NotifyDynamicSinks(msg, globalDynamicSinks, bCliSide, bStart, bAsync);
759 ArrayWithSize dynamicSinks = DynamicSinks;
760 if (dynamicSinks !=
null)
762 DynamicPropertyHolder.NotifyDynamicSinks(msg, dynamicSinks, bCliSide, bStart, bAsync);
virtual void SetProperty(IContextProperty prop)
Sets a specific context property by name.
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
Describes a set of security permissions applied to code. This class cannot be inherited.
static void FreeNamedDataSlot(string name)
Frees a named data slot on all the contexts.
static object GetData(LocalDataStoreSlot slot)
Retrieves the value from the specified slot on the current context.
Holds a message returned in response to a method call on a remote object.
Encapsulates a memory slot to store local data. This class cannot be inherited.
static void SetData(LocalDataStoreSlot slot, object data)
Sets the data in the specified slot on the current context.
Defines the method call return message interface.
IMessage SyncProcessMessage(IMessage msg)
Synchronously processes the given message.
Represents the construction call request of an object.
static Context DefaultContext
Gets the default context for the current application domain.
Gathers naming information from the context property and determines whether the new context is ok for...
Defines the method call message interface.
Indicates that the implementing property should be registered at runtime through the M:System....
virtual int ContextID
Gets the context ID for the current context.
override string ToString()
Returns a T:System.String class representation of the current context.
static void KeepAlive(object obj)
References the specified object, which makes it ineligible for garbage collection from the start of t...
void DoCallBack(CrossContextDelegate deleg)
Executes code in another context.
Defines an environment for the objects that are resident inside it and for which a policy can be enfo...
Indicates that the implementing property will be registered at runtime through the M:System....
IDictionary Properties
Gets an T:System.Collections.IDictionary that represents a collection of the message's properties.
string Name
Gets the name of the dynamic property.
Represents an application domain, which is an isolated environment where applications execute....
static bool UnregisterDynamicProperty(string name, ContextBoundObject obj, Context ctx)
Unregisters a dynamic property implementing the T:System.Runtime.Remoting.Contexts....
SecurityAction
Specifies the security actions that can be performed using declarative security.
Identifies a T:System.Runtime.Remoting.Messaging.IMethodReturnMessage that is returned after attempti...
Provides information about, and means to manipulate, the current environment and platform....
Defines the base class for all context-bound classes.
static int Increment(ref int location)
Increments a specified variable and stores the result, as an atomic operation.
static bool RegisterDynamicProperty(IDynamicProperty prop, ContextBoundObject obj, Context ctx)
Registers a dynamic property implementing the T:System.Runtime.Remoting.Contexts.IDynamicProperty int...
A platform-specific type that is used to represent a pointer or a handle.
virtual IContextProperty GetProperty(string name)
Returns a specific context property, specified by name.
delegate void CrossContextDelegate()
Represents the method that will handle the requests of execution of some code in another context.
Context()
Initializes a new instance of the T:System.Runtime.Remoting.Contexts.Context class.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
string Name
Gets the name of the property under which it will be added to the context.
MethodImplOptions
Defines the details of how a method is implemented.
static LocalDataStoreSlot GetNamedDataSlot(string name)
Looks up a named data slot.
static AppDomain GetDomain()
Returns the current domain in which the current thread is running.
Indicates that data in the pipe is transmitted and read as a stream of messages.
Provides a set of properties that are carried with the execution code path during remote method calls...
Controls the system garbage collector, a service that automatically reclaims unused memory.
Contains communication data sent between cooperating message sinks.
static LocalDataStoreSlot AllocateDataSlot()
Allocates an unnamed data slot.
virtual IContextProperty [] ContextProperties
Gets the array of the current context properties.
static LocalDataStoreSlot AllocateNamedDataSlot(string name)
Allocates a named data slot.
static CultureInfo CurrentCulture
Gets or sets the T:System.Globalization.CultureInfo object that represents the culture used by the cu...
The exception that is thrown when one of the arguments provided to a method is not valid.
static void Copy(Array sourceArray, Array destinationArray, int length)
Copies a range of elements from an T:System.Array starting at the first element and pastes them into ...
Defines the interface for a message sink.
The exception that is thrown when a method call is invalid for the object's current state.
Provides information about a specific culture (called a locale for unmanaged code development)....
void Freeze(Context newContext)
Called when the context is frozen.
SecurityPermissionFlag
Specifies access flags for the security permission object.
Provides atomic operations for variables that are shared by multiple threads.
static Context CurrentContext
Gets the current context in which the thread is executing.
The exception that is thrown when something has gone wrong during remoting.
Exception Exception
Gets the exception thrown during the method call.
virtual void Freeze()
Freezes the context, making it impossible to add or remove context properties from the current contex...
Creates and controls a thread, sets its priority, and gets its status.