Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Runtime / Remoting / TerminatorSinks.cs / 1305376 / TerminatorSinks.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // // Remoting terminator sinks for sink chains along a remoting call. // There is only one static instance of each of these exposed through // the MessageSink property. // namespace System.Runtime.Remoting.Messaging { using System; using System.Threading; using System.Runtime.InteropServices; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Contexts; using System.Collections; using System.Globalization; // Methods shared by all terminator sinks. // [Serializable] internal class InternalSink { /* * Checks the replySink param for NULL and type. * If the param is good, it returns NULL. * Else it returns a Message with the relevant exception. */ [System.Security.SecurityCritical] // auto-generated internal static IMessage ValidateMessage(IMessage reqMsg) { IMessage retMsg = null; if (reqMsg == null) { retMsg = new ReturnMessage( new ArgumentNullException("reqMsg"), null); } return retMsg; } /* * This check is performed only for client & server context * terminator sinks and only on the Async path. * */ [System.Security.SecurityCritical] // auto-generated internal static IMessage DisallowAsyncActivation(IMessage reqMsg) { // < if (reqMsg is IConstructionCallMessage) { return new ReturnMessage(new RemotingException(Environment.GetResourceString("Remoting_Activation_AsyncUnsupported")), null /*reqMsg*/ ); } return null; } [System.Security.SecurityCritical] // auto-generated internal static Identity GetIdentity(IMessage reqMsg) { Identity id = null; if (reqMsg is IInternalMessage) { id = ((IInternalMessage) reqMsg).IdentityObject; } else if (reqMsg is InternalMessageWrapper) { id = (Identity)((InternalMessageWrapper)reqMsg).GetIdentityObject(); } // Try the slow path if the identity has not been obtained yet if(null == id) { String objURI = GetURI(reqMsg); id = IdentityHolder.ResolveIdentity(objURI); // An object could get disconnected on another thread while a call is in progress if(id == null) { throw new ArgumentException(Environment.GetResourceString("Remoting_ServerObjectNotFound", objURI)); } } return id; } [System.Security.SecurityCritical] // auto-generated internal static ServerIdentity GetServerIdentity(IMessage reqMsg) { ServerIdentity srvID = null; bool bOurMsg = false; String objURI = null; IInternalMessage iim = reqMsg as IInternalMessage; if (iim != null) { Message.DebugOut("GetServerIdentity.ServerIdentity from IInternalMessage\n"); srvID = ((IInternalMessage) reqMsg).ServerIdentityObject; bOurMsg = true; } else if (reqMsg is InternalMessageWrapper) { srvID = (ServerIdentity)((InternalMessageWrapper)reqMsg).GetServerIdentityObject(); } // Try the slow path if the identity has not been obtained yet if(null == srvID) { Message.DebugOut("GetServerIdentity.ServerIdentity from IMethodCallMessage\n"); objURI = GetURI(reqMsg); Identity id = IdentityHolder.ResolveIdentity(objURI); if(id is ServerIdentity) { srvID = (ServerIdentity)id; // Cache the serverIdentity in the message if (bOurMsg) { iim.ServerIdentityObject = srvID; } } } return srvID; } // Retrieve the URI either via a method call or through // a dictionary property. [System.Security.SecurityCritical] // auto-generated internal static String GetURI(IMessage msg) { String uri = null; IMethodMessage mm = msg as IMethodMessage; if (mm != null) { uri = mm.Uri; } else { IDictionary prop = msg.Properties; if(null != prop) { uri = (String)prop["__Uri"]; } } return uri; } } // // Terminator sink for server envoy message sink chain. This delegates // to the client context chain for the call. // /* package scope */ [Serializable] internal class EnvoyTerminatorSink : InternalSink, IMessageSink { private static EnvoyTerminatorSink messageSink; private static Object staticSyncObject = new Object(); internal static IMessageSink MessageSink { get { if (messageSink == null) { EnvoyTerminatorSink tmpSink = new EnvoyTerminatorSink(); lock(staticSyncObject) { if (messageSink == null) { messageSink = tmpSink; } } } return messageSink; } } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { Message.DebugOut("---------------------------Envoy Chain Terminator: SyncProcessMessage"); IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { return errMsg; } // Validate returns null if the reqMsg is okay! return Thread.CurrentContext.GetClientContextChain().SyncProcessMessage(reqMsg); } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { Message.DebugOut("---------------------------Envoy Chain Terminator: AsyncProcessMessage"); IMessageCtrl msgCtrl = null; IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { // Notify replySink of error if we can // < if (replySink != null) { replySink.SyncProcessMessage(errMsg); } } else { msgCtrl = Thread.CurrentContext.GetClientContextChain().AsyncProcessMessage(reqMsg, replySink); } return msgCtrl; } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { // We are the terminal sink of this chain return null; } } } // // Terminator sink for client context message sink chain. This delegates // to the appropriate channel sink for the call. // // /* package scope */ internal class ClientContextTerminatorSink : InternalSink, IMessageSink { private static ClientContextTerminatorSink messageSink; private static Object staticSyncObject = new Object(); internal static IMessageSink MessageSink { get { if (messageSink == null) { ClientContextTerminatorSink tmpSink = new ClientContextTerminatorSink(); lock(staticSyncObject) { if (messageSink == null) { messageSink = tmpSink; } } } return messageSink; } } [System.Security.SecurityCritical] // auto-generated internal static Object SyncProcessMessageCallback(Object[] args) { IMessage reqMsg = (IMessage) args[0]; IMessageSink channelSink = (IMessageSink) args[1]; return channelSink.SyncProcessMessage(reqMsg); } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { Message.DebugOut("+++++++++++++++++++++++++ CliCtxTerminator: SyncProcessMsg"); IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { return errMsg; } Context ctx = Thread.CurrentContext; bool bHasDynamicSinks = ctx.NotifyDynamicSinks(reqMsg, true, // bCliSide true, // bStart false, // bAsync true); // bNotifyGlobals IMessage replyMsg; if (reqMsg is IConstructionCallMessage) { errMsg = ctx.NotifyActivatorProperties( reqMsg, false /*bServerSide*/); if (errMsg != null) { return errMsg; } replyMsg = ((IConstructionCallMessage)reqMsg).Activator.Activate( (IConstructionCallMessage)reqMsg); BCLDebug.Assert(replyMsg is IConstructionReturnMessage,"bad ctorRetMsg"); errMsg = ctx.NotifyActivatorProperties( replyMsg, false /*bServerSide*/); if (errMsg != null) { return errMsg; } } else { replyMsg = null; ChannelServices.NotifyProfiler(reqMsg, RemotingProfilerEvent.ClientSend); Object[] args = new Object[] { null, null }; IMessageSink channelSink = GetChannelSink(reqMsg); // Forward call to the channel. args[0] = reqMsg; args[1] = channelSink; InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(SyncProcessMessageCallback); // Move to default context unless we are going through // the cross-context channel if (channelSink != CrossContextChannel.MessageSink) { replyMsg = (IMessage) Thread.CurrentThread.InternalCrossContextCallback(Context.DefaultContext, xctxDel, args); } else { replyMsg = (IMessage) xctxDel(args); } ChannelServices.NotifyProfiler(replyMsg, RemotingProfilerEvent.ClientReceive); } if (bHasDynamicSinks) { ctx.NotifyDynamicSinks(reqMsg, true, // bCliSide false, // bStart false, // bAsync true); // bNotifyGlobals } return replyMsg; } [System.Security.SecurityCritical] // auto-generated internal static Object AsyncProcessMessageCallback(Object[] args) { IMessage reqMsg = (IMessage) args[0]; IMessageSink replySink = (IMessageSink) args[1]; IMessageSink channelSink = (IMessageSink) args[2]; return channelSink.AsyncProcessMessage(reqMsg, replySink); } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { Message.DebugOut("+++++++++++++++++++++++++ CliCtxTerminator: AsyncProcessMsg"); IMessage errMsg = ValidateMessage(reqMsg); IMessageCtrl msgCtrl=null; if (errMsg == null) { errMsg = DisallowAsyncActivation(reqMsg); } if (errMsg != null) { if (replySink != null) { replySink.SyncProcessMessage(errMsg); } } else { // If active, notify the profiler that an asynchronous remoting call is being made. if (RemotingServices.CORProfilerTrackRemotingAsync()) { Guid g; RemotingServices.CORProfilerRemotingClientSendingMessage(out g, true); if (RemotingServices.CORProfilerTrackRemotingCookie()) reqMsg.Properties["CORProfilerCookie"] = g; // Only wrap the replySink if the call wants a reply if (replySink != null) { // Now wrap the reply sink in our own so that we can notify the profiler of // when the reply is received. Upon invocation, it will notify the profiler // then pass control on to the replySink passed in above. IMessageSink profSink = new ClientAsyncReplyTerminatorSink(replySink); // Replace the reply sink with our own replySink = profSink; } } Context cliCtx = Thread.CurrentContext; // Notify dynamic sinks that an Async call started cliCtx.NotifyDynamicSinks( reqMsg, true, // bCliSide true, // bStart true, // bAsync true); // bNotifyGlobals // Intercept the async reply to force the thread back // into the client-context before it executes further // and to notify dynamic sinks if (replySink != null) { replySink = new AsyncReplySink(replySink, cliCtx); } Object[] args = new Object[] { null, null, null }; InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(AsyncProcessMessageCallback); IMessageSink channelSink = GetChannelSink(reqMsg); // Forward call to the channel. args[0] = reqMsg; args[1] = replySink; args[2] = channelSink; // Move to default context unless we are going through // the cross-context channel if (channelSink != CrossContextChannel.MessageSink) { msgCtrl = (IMessageCtrl) Thread.CurrentThread.InternalCrossContextCallback(Context.DefaultContext, xctxDel, args); } else { msgCtrl = (IMessageCtrl) xctxDel(args); } } return msgCtrl; } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { // We are the terminal sink of this chain return null; } } // Find the next chain (or channel) sink to delegate to. [System.Security.SecurityCritical] // auto-generated private IMessageSink GetChannelSink(IMessage reqMsg) { Identity id = GetIdentity(reqMsg); return id.ChannelSink; } } internal class AsyncReplySink : IMessageSink { IMessageSink _replySink;// original reply sink that we are wrapping Context _cliCtx; // the context this call emerged from internal AsyncReplySink(IMessageSink replySink, Context cliCtx) { _replySink = replySink; _cliCtx = cliCtx; } [System.Security.SecurityCritical] // auto-generated internal static Object SyncProcessMessageCallback(Object[] args) { IMessage reqMsg = (IMessage) args[0]; IMessageSink replySink = (IMessageSink) args[1]; // Call the dynamic sinks to notify that the async call // has completed Thread.CurrentContext.NotifyDynamicSinks( reqMsg, // this is the async reply true, // bCliSide false, // bStart true, // bAsync true); // bNotifyGlobals // call the original reply sink now that we have moved // to the correct client context return replySink.SyncProcessMessage(reqMsg); } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { // we just switch back to the old context before calling // the next replySink IMessage retMsg = null; if (_replySink != null) { Object[] args = new Object[] { reqMsg, _replySink }; InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(SyncProcessMessageCallback); retMsg = (IMessage) Thread.CurrentThread.InternalCrossContextCallback(_cliCtx, xctxDel, args); } return retMsg; } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage( IMessage reqMsg, IMessageSink replySink) { throw new NotSupportedException(); } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { return _replySink; } } } // // Terminator sink for server context message sink chain. This delegates // to the appropriate object sink chain for the call. // // /* package scope */ [Serializable] internal class ServerContextTerminatorSink : InternalSink, IMessageSink { private static ServerContextTerminatorSink messageSink; private static Object staticSyncObject = new Object(); internal static IMessageSink MessageSink { get { if (messageSink == null) { ServerContextTerminatorSink tmpSink = new ServerContextTerminatorSink(); lock(staticSyncObject) { if (messageSink == null) { messageSink = tmpSink; } } } return messageSink; } } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { Message.DebugOut("+++++++++++++++++++++++++ SrvCtxTerminator: SyncProcessMsg"); IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { return errMsg; } Context ctx = Thread.CurrentContext; IMessage replyMsg; if (reqMsg is IConstructionCallMessage) { errMsg = ctx.NotifyActivatorProperties( reqMsg, true /*bServerSide*/); if (errMsg != null) { return errMsg; } replyMsg = ((IConstructionCallMessage)reqMsg).Activator.Activate((IConstructionCallMessage)reqMsg); BCLDebug.Assert(replyMsg is IConstructionReturnMessage,"bad ctorRetMsg"); errMsg = ctx.NotifyActivatorProperties( replyMsg, true /*bServerSide*/); if (errMsg != null) { return errMsg; } } else { // Pass call on to the server object specific chain MarshalByRefObject obj = null; try{ replyMsg = GetObjectChain(reqMsg, out obj).SyncProcessMessage(reqMsg); } finally { IDisposable iDis = null; if (obj != null && ((iDis=(obj as IDisposable)) != null)) { iDis.Dispose(); } } } return replyMsg; } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { Message.DebugOut("+++++++++++++++++++++++++ SrvCtxTerminator: SyncProcessMsg"); IMessageCtrl msgCtrl=null; IMessage errMsg = ValidateMessage(reqMsg); if (errMsg == null) { errMsg = DisallowAsyncActivation(reqMsg); } if (errMsg != null) { if (replySink!=null) { replySink.SyncProcessMessage(errMsg); } } else { // < MarshalByRefObject obj; IMessageSink nextChain = GetObjectChain(reqMsg, out obj); IDisposable iDis; if (obj != null && ((iDis = (obj as IDisposable)) != null)) { DisposeSink dsink = new DisposeSink(iDis, replySink); replySink = dsink; } msgCtrl = nextChain.AsyncProcessMessage( reqMsg, replySink); } return msgCtrl; } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { // We are the terminal sink of this chain return null; } } [System.Security.SecurityCritical] // auto-generated internal virtual IMessageSink GetObjectChain(IMessage reqMsg,out MarshalByRefObject obj) { ServerIdentity srvID = GetServerIdentity(reqMsg); return srvID.GetServerObjectChain(out obj); } } internal class DisposeSink : IMessageSink { IDisposable _iDis; IMessageSink _replySink; internal DisposeSink(IDisposable iDis, IMessageSink replySink) { _iDis = iDis; _replySink = replySink; } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { IMessage replyMsg = null; try{ if (_replySink != null) { replyMsg = _replySink.SyncProcessMessage(reqMsg); } } finally{ // call dispose on the object now! _iDis.Dispose(); } return replyMsg; } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { throw new NotSupportedException(); } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { return _replySink; } } } // // Terminator sink for the server object sink chain. This should // be just replaced by the dispatcher sink. // /* package scope */ [Serializable] internal class ServerObjectTerminatorSink : InternalSink, IMessageSink { internal StackBuilderSink _stackBuilderSink; internal ServerObjectTerminatorSink(MarshalByRefObject srvObj) { _stackBuilderSink = new StackBuilderSink(srvObj); } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { Message.DebugOut("+++++++++++++++++++++++++ SrvObjTerminator: SyncProcessMsg\n"); IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { return errMsg; } ServerIdentity srvID = GetServerIdentity(reqMsg); BCLDebug.Assert(null != srvID,"null != srvID"); ArrayWithSize objectSinks = srvID.ServerSideDynamicSinks; if (objectSinks != null) { DynamicPropertyHolder.NotifyDynamicSinks( reqMsg, objectSinks, false, // bCliSide true, // bStart false); // bAsync } Message.DebugOut("ServerObjectTerminator.Invoking method on object\n"); // Pass call on to the server object specific chain BCLDebug.Assert(null != _stackBuilderSink,"null != _stackBuilderSink"); IMessage replyMsg; IMessageSink serverAsSink = _stackBuilderSink.ServerObject as IMessageSink; if (serverAsSink != null) replyMsg = serverAsSink.SyncProcessMessage(reqMsg); else replyMsg = _stackBuilderSink.SyncProcessMessage(reqMsg); if (objectSinks != null) { DynamicPropertyHolder.NotifyDynamicSinks( replyMsg, objectSinks, false, // bCliSide false, // bStart false); // bAsync } return replyMsg; } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { IMessageCtrl msgCtrl=null; IMessage errMsg = ValidateMessage(reqMsg); // < if (errMsg!=null) { if (replySink!=null) { replySink.SyncProcessMessage(errMsg); } } else { // Pass call on to the server object specific chain IMessageSink serverAsSink = _stackBuilderSink.ServerObject as IMessageSink; if (serverAsSink != null) msgCtrl = serverAsSink.AsyncProcessMessage(reqMsg, replySink); else msgCtrl = _stackBuilderSink.AsyncProcessMessage(reqMsg, replySink); } return msgCtrl; } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { // We are the terminal sink of this chain return null; } } } // // Terminator sink used for profiling so that we can intercept asynchronous // replies on the client side. // /* package scope */ internal class ClientAsyncReplyTerminatorSink : IMessageSink { internal IMessageSink _nextSink; internal ClientAsyncReplyTerminatorSink(IMessageSink nextSink) { BCLDebug.Assert(nextSink != null, "null IMessageSink passed to ClientAsyncReplyTerminatorSink ctor."); _nextSink = nextSink; } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage replyMsg) { // If this class has been brought into the picture, then the following must be true. BCLDebug.Assert(RemotingServices.CORProfilerTrackRemoting(), "CORProfilerTrackRemoting returned false, but we're in AsyncProcessMessage!"); BCLDebug.Assert(RemotingServices.CORProfilerTrackRemotingAsync(), "CORProfilerTrackRemoting returned false, but we're in AsyncProcessMessage!"); Guid g = Guid.Empty; // If GUID cookies are active, then we try to get it from the properties dictionary if (RemotingServices.CORProfilerTrackRemotingCookie()) { Object obj = replyMsg.Properties["CORProfilerCookie"]; if (obj != null) { g = (Guid) obj; } } // Notify the profiler that we are receiving an async reply from the server-side RemotingServices.CORProfilerRemotingClientReceivingReply(g, true); // Now that we've done the intercepting, pass the message on to the regular chain return _nextSink.SyncProcessMessage(replyMsg); } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage replyMsg, IMessageSink replySink) { // Since this class is only used for intercepting async replies, this function should // never get called. (Async replies are synchronous, ironically) BCLDebug.Assert(false, "ClientAsyncReplyTerminatorSink.AsyncProcessMessage called!"); return null; } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { return _nextSink; } } // Do I need a finalize here? } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // // Remoting terminator sinks for sink chains along a remoting call. // There is only one static instance of each of these exposed through // the MessageSink property. // namespace System.Runtime.Remoting.Messaging { using System; using System.Threading; using System.Runtime.InteropServices; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Contexts; using System.Collections; using System.Globalization; // Methods shared by all terminator sinks. // [Serializable] internal class InternalSink { /* * Checks the replySink param for NULL and type. * If the param is good, it returns NULL. * Else it returns a Message with the relevant exception. */ [System.Security.SecurityCritical] // auto-generated internal static IMessage ValidateMessage(IMessage reqMsg) { IMessage retMsg = null; if (reqMsg == null) { retMsg = new ReturnMessage( new ArgumentNullException("reqMsg"), null); } return retMsg; } /* * This check is performed only for client & server context * terminator sinks and only on the Async path. * */ [System.Security.SecurityCritical] // auto-generated internal static IMessage DisallowAsyncActivation(IMessage reqMsg) { // < if (reqMsg is IConstructionCallMessage) { return new ReturnMessage(new RemotingException(Environment.GetResourceString("Remoting_Activation_AsyncUnsupported")), null /*reqMsg*/ ); } return null; } [System.Security.SecurityCritical] // auto-generated internal static Identity GetIdentity(IMessage reqMsg) { Identity id = null; if (reqMsg is IInternalMessage) { id = ((IInternalMessage) reqMsg).IdentityObject; } else if (reqMsg is InternalMessageWrapper) { id = (Identity)((InternalMessageWrapper)reqMsg).GetIdentityObject(); } // Try the slow path if the identity has not been obtained yet if(null == id) { String objURI = GetURI(reqMsg); id = IdentityHolder.ResolveIdentity(objURI); // An object could get disconnected on another thread while a call is in progress if(id == null) { throw new ArgumentException(Environment.GetResourceString("Remoting_ServerObjectNotFound", objURI)); } } return id; } [System.Security.SecurityCritical] // auto-generated internal static ServerIdentity GetServerIdentity(IMessage reqMsg) { ServerIdentity srvID = null; bool bOurMsg = false; String objURI = null; IInternalMessage iim = reqMsg as IInternalMessage; if (iim != null) { Message.DebugOut("GetServerIdentity.ServerIdentity from IInternalMessage\n"); srvID = ((IInternalMessage) reqMsg).ServerIdentityObject; bOurMsg = true; } else if (reqMsg is InternalMessageWrapper) { srvID = (ServerIdentity)((InternalMessageWrapper)reqMsg).GetServerIdentityObject(); } // Try the slow path if the identity has not been obtained yet if(null == srvID) { Message.DebugOut("GetServerIdentity.ServerIdentity from IMethodCallMessage\n"); objURI = GetURI(reqMsg); Identity id = IdentityHolder.ResolveIdentity(objURI); if(id is ServerIdentity) { srvID = (ServerIdentity)id; // Cache the serverIdentity in the message if (bOurMsg) { iim.ServerIdentityObject = srvID; } } } return srvID; } // Retrieve the URI either via a method call or through // a dictionary property. [System.Security.SecurityCritical] // auto-generated internal static String GetURI(IMessage msg) { String uri = null; IMethodMessage mm = msg as IMethodMessage; if (mm != null) { uri = mm.Uri; } else { IDictionary prop = msg.Properties; if(null != prop) { uri = (String)prop["__Uri"]; } } return uri; } } // // Terminator sink for server envoy message sink chain. This delegates // to the client context chain for the call. // /* package scope */ [Serializable] internal class EnvoyTerminatorSink : InternalSink, IMessageSink { private static EnvoyTerminatorSink messageSink; private static Object staticSyncObject = new Object(); internal static IMessageSink MessageSink { get { if (messageSink == null) { EnvoyTerminatorSink tmpSink = new EnvoyTerminatorSink(); lock(staticSyncObject) { if (messageSink == null) { messageSink = tmpSink; } } } return messageSink; } } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { Message.DebugOut("---------------------------Envoy Chain Terminator: SyncProcessMessage"); IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { return errMsg; } // Validate returns null if the reqMsg is okay! return Thread.CurrentContext.GetClientContextChain().SyncProcessMessage(reqMsg); } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { Message.DebugOut("---------------------------Envoy Chain Terminator: AsyncProcessMessage"); IMessageCtrl msgCtrl = null; IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { // Notify replySink of error if we can // < if (replySink != null) { replySink.SyncProcessMessage(errMsg); } } else { msgCtrl = Thread.CurrentContext.GetClientContextChain().AsyncProcessMessage(reqMsg, replySink); } return msgCtrl; } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { // We are the terminal sink of this chain return null; } } } // // Terminator sink for client context message sink chain. This delegates // to the appropriate channel sink for the call. // // /* package scope */ internal class ClientContextTerminatorSink : InternalSink, IMessageSink { private static ClientContextTerminatorSink messageSink; private static Object staticSyncObject = new Object(); internal static IMessageSink MessageSink { get { if (messageSink == null) { ClientContextTerminatorSink tmpSink = new ClientContextTerminatorSink(); lock(staticSyncObject) { if (messageSink == null) { messageSink = tmpSink; } } } return messageSink; } } [System.Security.SecurityCritical] // auto-generated internal static Object SyncProcessMessageCallback(Object[] args) { IMessage reqMsg = (IMessage) args[0]; IMessageSink channelSink = (IMessageSink) args[1]; return channelSink.SyncProcessMessage(reqMsg); } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { Message.DebugOut("+++++++++++++++++++++++++ CliCtxTerminator: SyncProcessMsg"); IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { return errMsg; } Context ctx = Thread.CurrentContext; bool bHasDynamicSinks = ctx.NotifyDynamicSinks(reqMsg, true, // bCliSide true, // bStart false, // bAsync true); // bNotifyGlobals IMessage replyMsg; if (reqMsg is IConstructionCallMessage) { errMsg = ctx.NotifyActivatorProperties( reqMsg, false /*bServerSide*/); if (errMsg != null) { return errMsg; } replyMsg = ((IConstructionCallMessage)reqMsg).Activator.Activate( (IConstructionCallMessage)reqMsg); BCLDebug.Assert(replyMsg is IConstructionReturnMessage,"bad ctorRetMsg"); errMsg = ctx.NotifyActivatorProperties( replyMsg, false /*bServerSide*/); if (errMsg != null) { return errMsg; } } else { replyMsg = null; ChannelServices.NotifyProfiler(reqMsg, RemotingProfilerEvent.ClientSend); Object[] args = new Object[] { null, null }; IMessageSink channelSink = GetChannelSink(reqMsg); // Forward call to the channel. args[0] = reqMsg; args[1] = channelSink; InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(SyncProcessMessageCallback); // Move to default context unless we are going through // the cross-context channel if (channelSink != CrossContextChannel.MessageSink) { replyMsg = (IMessage) Thread.CurrentThread.InternalCrossContextCallback(Context.DefaultContext, xctxDel, args); } else { replyMsg = (IMessage) xctxDel(args); } ChannelServices.NotifyProfiler(replyMsg, RemotingProfilerEvent.ClientReceive); } if (bHasDynamicSinks) { ctx.NotifyDynamicSinks(reqMsg, true, // bCliSide false, // bStart false, // bAsync true); // bNotifyGlobals } return replyMsg; } [System.Security.SecurityCritical] // auto-generated internal static Object AsyncProcessMessageCallback(Object[] args) { IMessage reqMsg = (IMessage) args[0]; IMessageSink replySink = (IMessageSink) args[1]; IMessageSink channelSink = (IMessageSink) args[2]; return channelSink.AsyncProcessMessage(reqMsg, replySink); } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { Message.DebugOut("+++++++++++++++++++++++++ CliCtxTerminator: AsyncProcessMsg"); IMessage errMsg = ValidateMessage(reqMsg); IMessageCtrl msgCtrl=null; if (errMsg == null) { errMsg = DisallowAsyncActivation(reqMsg); } if (errMsg != null) { if (replySink != null) { replySink.SyncProcessMessage(errMsg); } } else { // If active, notify the profiler that an asynchronous remoting call is being made. if (RemotingServices.CORProfilerTrackRemotingAsync()) { Guid g; RemotingServices.CORProfilerRemotingClientSendingMessage(out g, true); if (RemotingServices.CORProfilerTrackRemotingCookie()) reqMsg.Properties["CORProfilerCookie"] = g; // Only wrap the replySink if the call wants a reply if (replySink != null) { // Now wrap the reply sink in our own so that we can notify the profiler of // when the reply is received. Upon invocation, it will notify the profiler // then pass control on to the replySink passed in above. IMessageSink profSink = new ClientAsyncReplyTerminatorSink(replySink); // Replace the reply sink with our own replySink = profSink; } } Context cliCtx = Thread.CurrentContext; // Notify dynamic sinks that an Async call started cliCtx.NotifyDynamicSinks( reqMsg, true, // bCliSide true, // bStart true, // bAsync true); // bNotifyGlobals // Intercept the async reply to force the thread back // into the client-context before it executes further // and to notify dynamic sinks if (replySink != null) { replySink = new AsyncReplySink(replySink, cliCtx); } Object[] args = new Object[] { null, null, null }; InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(AsyncProcessMessageCallback); IMessageSink channelSink = GetChannelSink(reqMsg); // Forward call to the channel. args[0] = reqMsg; args[1] = replySink; args[2] = channelSink; // Move to default context unless we are going through // the cross-context channel if (channelSink != CrossContextChannel.MessageSink) { msgCtrl = (IMessageCtrl) Thread.CurrentThread.InternalCrossContextCallback(Context.DefaultContext, xctxDel, args); } else { msgCtrl = (IMessageCtrl) xctxDel(args); } } return msgCtrl; } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { // We are the terminal sink of this chain return null; } } // Find the next chain (or channel) sink to delegate to. [System.Security.SecurityCritical] // auto-generated private IMessageSink GetChannelSink(IMessage reqMsg) { Identity id = GetIdentity(reqMsg); return id.ChannelSink; } } internal class AsyncReplySink : IMessageSink { IMessageSink _replySink;// original reply sink that we are wrapping Context _cliCtx; // the context this call emerged from internal AsyncReplySink(IMessageSink replySink, Context cliCtx) { _replySink = replySink; _cliCtx = cliCtx; } [System.Security.SecurityCritical] // auto-generated internal static Object SyncProcessMessageCallback(Object[] args) { IMessage reqMsg = (IMessage) args[0]; IMessageSink replySink = (IMessageSink) args[1]; // Call the dynamic sinks to notify that the async call // has completed Thread.CurrentContext.NotifyDynamicSinks( reqMsg, // this is the async reply true, // bCliSide false, // bStart true, // bAsync true); // bNotifyGlobals // call the original reply sink now that we have moved // to the correct client context return replySink.SyncProcessMessage(reqMsg); } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { // we just switch back to the old context before calling // the next replySink IMessage retMsg = null; if (_replySink != null) { Object[] args = new Object[] { reqMsg, _replySink }; InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(SyncProcessMessageCallback); retMsg = (IMessage) Thread.CurrentThread.InternalCrossContextCallback(_cliCtx, xctxDel, args); } return retMsg; } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage( IMessage reqMsg, IMessageSink replySink) { throw new NotSupportedException(); } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { return _replySink; } } } // // Terminator sink for server context message sink chain. This delegates // to the appropriate object sink chain for the call. // // /* package scope */ [Serializable] internal class ServerContextTerminatorSink : InternalSink, IMessageSink { private static ServerContextTerminatorSink messageSink; private static Object staticSyncObject = new Object(); internal static IMessageSink MessageSink { get { if (messageSink == null) { ServerContextTerminatorSink tmpSink = new ServerContextTerminatorSink(); lock(staticSyncObject) { if (messageSink == null) { messageSink = tmpSink; } } } return messageSink; } } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { Message.DebugOut("+++++++++++++++++++++++++ SrvCtxTerminator: SyncProcessMsg"); IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { return errMsg; } Context ctx = Thread.CurrentContext; IMessage replyMsg; if (reqMsg is IConstructionCallMessage) { errMsg = ctx.NotifyActivatorProperties( reqMsg, true /*bServerSide*/); if (errMsg != null) { return errMsg; } replyMsg = ((IConstructionCallMessage)reqMsg).Activator.Activate((IConstructionCallMessage)reqMsg); BCLDebug.Assert(replyMsg is IConstructionReturnMessage,"bad ctorRetMsg"); errMsg = ctx.NotifyActivatorProperties( replyMsg, true /*bServerSide*/); if (errMsg != null) { return errMsg; } } else { // Pass call on to the server object specific chain MarshalByRefObject obj = null; try{ replyMsg = GetObjectChain(reqMsg, out obj).SyncProcessMessage(reqMsg); } finally { IDisposable iDis = null; if (obj != null && ((iDis=(obj as IDisposable)) != null)) { iDis.Dispose(); } } } return replyMsg; } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { Message.DebugOut("+++++++++++++++++++++++++ SrvCtxTerminator: SyncProcessMsg"); IMessageCtrl msgCtrl=null; IMessage errMsg = ValidateMessage(reqMsg); if (errMsg == null) { errMsg = DisallowAsyncActivation(reqMsg); } if (errMsg != null) { if (replySink!=null) { replySink.SyncProcessMessage(errMsg); } } else { // < MarshalByRefObject obj; IMessageSink nextChain = GetObjectChain(reqMsg, out obj); IDisposable iDis; if (obj != null && ((iDis = (obj as IDisposable)) != null)) { DisposeSink dsink = new DisposeSink(iDis, replySink); replySink = dsink; } msgCtrl = nextChain.AsyncProcessMessage( reqMsg, replySink); } return msgCtrl; } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { // We are the terminal sink of this chain return null; } } [System.Security.SecurityCritical] // auto-generated internal virtual IMessageSink GetObjectChain(IMessage reqMsg,out MarshalByRefObject obj) { ServerIdentity srvID = GetServerIdentity(reqMsg); return srvID.GetServerObjectChain(out obj); } } internal class DisposeSink : IMessageSink { IDisposable _iDis; IMessageSink _replySink; internal DisposeSink(IDisposable iDis, IMessageSink replySink) { _iDis = iDis; _replySink = replySink; } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { IMessage replyMsg = null; try{ if (_replySink != null) { replyMsg = _replySink.SyncProcessMessage(reqMsg); } } finally{ // call dispose on the object now! _iDis.Dispose(); } return replyMsg; } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { throw new NotSupportedException(); } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { return _replySink; } } } // // Terminator sink for the server object sink chain. This should // be just replaced by the dispatcher sink. // /* package scope */ [Serializable] internal class ServerObjectTerminatorSink : InternalSink, IMessageSink { internal StackBuilderSink _stackBuilderSink; internal ServerObjectTerminatorSink(MarshalByRefObject srvObj) { _stackBuilderSink = new StackBuilderSink(srvObj); } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage reqMsg) { Message.DebugOut("+++++++++++++++++++++++++ SrvObjTerminator: SyncProcessMsg\n"); IMessage errMsg = ValidateMessage(reqMsg); if (errMsg != null) { return errMsg; } ServerIdentity srvID = GetServerIdentity(reqMsg); BCLDebug.Assert(null != srvID,"null != srvID"); ArrayWithSize objectSinks = srvID.ServerSideDynamicSinks; if (objectSinks != null) { DynamicPropertyHolder.NotifyDynamicSinks( reqMsg, objectSinks, false, // bCliSide true, // bStart false); // bAsync } Message.DebugOut("ServerObjectTerminator.Invoking method on object\n"); // Pass call on to the server object specific chain BCLDebug.Assert(null != _stackBuilderSink,"null != _stackBuilderSink"); IMessage replyMsg; IMessageSink serverAsSink = _stackBuilderSink.ServerObject as IMessageSink; if (serverAsSink != null) replyMsg = serverAsSink.SyncProcessMessage(reqMsg); else replyMsg = _stackBuilderSink.SyncProcessMessage(reqMsg); if (objectSinks != null) { DynamicPropertyHolder.NotifyDynamicSinks( replyMsg, objectSinks, false, // bCliSide false, // bStart false); // bAsync } return replyMsg; } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { IMessageCtrl msgCtrl=null; IMessage errMsg = ValidateMessage(reqMsg); // < if (errMsg!=null) { if (replySink!=null) { replySink.SyncProcessMessage(errMsg); } } else { // Pass call on to the server object specific chain IMessageSink serverAsSink = _stackBuilderSink.ServerObject as IMessageSink; if (serverAsSink != null) msgCtrl = serverAsSink.AsyncProcessMessage(reqMsg, replySink); else msgCtrl = _stackBuilderSink.AsyncProcessMessage(reqMsg, replySink); } return msgCtrl; } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { // We are the terminal sink of this chain return null; } } } // // Terminator sink used for profiling so that we can intercept asynchronous // replies on the client side. // /* package scope */ internal class ClientAsyncReplyTerminatorSink : IMessageSink { internal IMessageSink _nextSink; internal ClientAsyncReplyTerminatorSink(IMessageSink nextSink) { BCLDebug.Assert(nextSink != null, "null IMessageSink passed to ClientAsyncReplyTerminatorSink ctor."); _nextSink = nextSink; } [System.Security.SecurityCritical] // auto-generated public virtual IMessage SyncProcessMessage(IMessage replyMsg) { // If this class has been brought into the picture, then the following must be true. BCLDebug.Assert(RemotingServices.CORProfilerTrackRemoting(), "CORProfilerTrackRemoting returned false, but we're in AsyncProcessMessage!"); BCLDebug.Assert(RemotingServices.CORProfilerTrackRemotingAsync(), "CORProfilerTrackRemoting returned false, but we're in AsyncProcessMessage!"); Guid g = Guid.Empty; // If GUID cookies are active, then we try to get it from the properties dictionary if (RemotingServices.CORProfilerTrackRemotingCookie()) { Object obj = replyMsg.Properties["CORProfilerCookie"]; if (obj != null) { g = (Guid) obj; } } // Notify the profiler that we are receiving an async reply from the server-side RemotingServices.CORProfilerRemotingClientReceivingReply(g, true); // Now that we've done the intercepting, pass the message on to the regular chain return _nextSink.SyncProcessMessage(replyMsg); } [System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage replyMsg, IMessageSink replySink) { // Since this class is only used for intercepting async replies, this function should // never get called. (Async replies are synchronous, ironically) BCLDebug.Assert(false, "ClientAsyncReplyTerminatorSink.AsyncProcessMessage called!"); return null; } public IMessageSink NextSink { [System.Security.SecurityCritical] // auto-generated get { return _nextSink; } } // Do I need a finalize here? } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ExpressionReplacer.cs
- TouchFrameEventArgs.cs
- SigningCredentials.cs
- SafeHandles.cs
- XmlElement.cs
- CustomCredentialPolicy.cs
- BindingEntityInfo.cs
- EDesignUtil.cs
- ImageIndexEditor.cs
- PositiveTimeSpanValidatorAttribute.cs
- Attribute.cs
- TypeLibConverter.cs
- WindowsRichEdit.cs
- SecurityHelper.cs
- MatrixTransform3D.cs
- ProfileEventArgs.cs
- ErrorRuntimeConfig.cs
- FixedDocumentPaginator.cs
- ValueSerializerAttribute.cs
- ObjectStateManagerMetadata.cs
- SharedUtils.cs
- ValidatorCollection.cs
- ObjectNavigationPropertyMapping.cs
- CompiledRegexRunnerFactory.cs
- MenuStrip.cs
- Errors.cs
- MemberRelationshipService.cs
- DesignTimeParseData.cs
- TrackingSection.cs
- ViewEventArgs.cs
- Button.cs
- BackStopAuthenticationModule.cs
- XPathBinder.cs
- Flattener.cs
- SQLInt16Storage.cs
- ParallelTimeline.cs
- PackagePartCollection.cs
- ControlParameter.cs
- SqlCacheDependencySection.cs
- TemplateControlCodeDomTreeGenerator.cs
- ClientSession.cs
- OdbcCommand.cs
- WebPartCloseVerb.cs
- RoleManagerEventArgs.cs
- SecurityDescriptor.cs
- PageSettings.cs
- CustomAttributeSerializer.cs
- StateWorkerRequest.cs
- EventSourceCreationData.cs
- AuthenticationConfig.cs
- DataGridViewSelectedCellsAccessibleObject.cs
- RegionInfo.cs
- OledbConnectionStringbuilder.cs
- ModelItemKeyValuePair.cs
- ZipIOLocalFileHeader.cs
- RenderData.cs
- InvalidCastException.cs
- SQLSingleStorage.cs
- UnionExpr.cs
- AttachedAnnotation.cs
- SqlProvider.cs
- BaseParser.cs
- ClientRolePrincipal.cs
- AccessibilityHelperForVista.cs
- RemoteWebConfigurationHostStream.cs
- HijriCalendar.cs
- BinaryObjectInfo.cs
- PermissionAttributes.cs
- SystemInformation.cs
- LedgerEntryCollection.cs
- ComponentSerializationService.cs
- ListSourceHelper.cs
- DataControlLinkButton.cs
- ActionItem.cs
- Choices.cs
- cookiecontainer.cs
- ResourceLoader.cs
- ReferencedCollectionType.cs
- XmlDocumentType.cs
- CommandID.cs
- ButtonBaseAdapter.cs
- URIFormatException.cs
- SkinBuilder.cs
- CursorInteropHelper.cs
- NullRuntimeConfig.cs
- TagNameToTypeMapper.cs
- StackOverflowException.cs
- SystemIPGlobalProperties.cs
- CategoryState.cs
- SqlTriggerAttribute.cs
- DbCommandTree.cs
- PromptBuilder.cs
- XmlBinaryReader.cs
- StreamGeometry.cs
- DataGridViewRowsRemovedEventArgs.cs
- Freezable.cs
- ReflectionPermission.cs
- CommandField.cs
- ExpandCollapseIsCheckedConverter.cs
- ProviderConnectionPointCollection.cs