public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { IMessage message = InternalSink.ValidateMessage(reqMsg); IMessageCtrl result = null; if (message == null) { message = InternalSink.DisallowAsyncActivation(reqMsg); } if (message != null) { if (replySink != null) { replySink.SyncProcessMessage(message); } } else { if (RemotingServices.CORProfilerTrackRemotingAsync()) { Guid guid; RemotingServices.CORProfilerRemotingClientSendingMessage(out guid, true); if (RemotingServices.CORProfilerTrackRemotingCookie()) { reqMsg.Properties["CORProfilerCookie"] = guid; } if (replySink != null) { IMessageSink messageSink = new ClientAsyncReplyTerminatorSink(replySink); replySink = messageSink; } } Context currentContext = Thread.CurrentContext; currentContext.NotifyDynamicSinks(reqMsg, true, true, true, true); if (replySink != null) { replySink = new AsyncReplySink(replySink, currentContext); } object[] array = new object[3]; InternalCrossContextDelegate internalCrossContextDelegate = new InternalCrossContextDelegate(ClientContextTerminatorSink.AsyncProcessMessageCallback); IMessageSink channelSink = this.GetChannelSink(reqMsg); array[0] = reqMsg; array[1] = replySink; array[2] = channelSink; if (channelSink != CrossContextChannel.MessageSink) { result = (IMessageCtrl)Thread.CurrentThread.InternalCrossContextCallback(Context.DefaultContext, internalCrossContextDelegate, array); } else { result = (IMessageCtrl)internalCrossContextDelegate(array); } } return(result); }
[System.Security.SecurityCritical] // auto-generated public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) { IMessageCtrl msgCtrl = null; Contract.Assert(_property.Locked == true,"_property.Locked == true"); if (!_property.IsReEntrant) { // In this case new calls are not allowed to enter the domain // We need to track potentially more than one async-call-outs // and allow the completion notifications to come in for those LogicalCallContext cctx = (LogicalCallContext) reqMsg.Properties[Message.CallContextKey]; // We used to generate a new lcid automatically in RemotingProxy // Invoke at the start of each Async call. // However now we do it here as an optimization (since only // Synchronization needs it) // RemotingProxy invoke code does Clone() the callContext at // the start of each Async call so we don't have to worry // about stomping someone else's lcid here. String lcid = Identity.GetNewLogicalCallID(); cctx.RemotingData.LogicalCallID = lcid; Contract.Assert( _property.SyncCallOutLCID == null, "Cannot handle async call outs when already in a top-level [....] call out"); //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] NR: Async CallOut: adding to lcidList: " + lcid); _property.AsyncCallOutLCIDList.Add(lcid); } // We will call AsyncProcessMessage directly on this thread // since the thread should not block much. However, we will // have to intercept the callback on the replySink chain for // which we wrap the caller provided replySink into our sink. AsyncReplySink mySink = new AsyncReplySink(replySink, _property); // NOTE: we will need to yield the Synchronization Domain at // some time or another to get our own callBack to complete. // Note that for the Async call-outs we have to provide an interception // sink whether we are re-entrant or not since we want // the replySink.SyncProcessMessage call to be wait for the lock just like // any other call-in. //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] Async call-out"); msgCtrl = _nextSink.AsyncProcessMessage(reqMsg, (IMessageSink)mySink); //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] Async call-out AsyncPM returned, reply to come separately"); return msgCtrl; }
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); } // Forward call to the channel. IMessageSink channelSink = GetChannelSink(reqMsg); // Move to default context unless we are going through // the cross-context channel ContextTransitionFrame frame = new ContextTransitionFrame(); if (channelSink != CrossContextChannel.MessageSink) { Thread.CurrentThread.EnterContext( Context.DefaultContext, ref frame); } msgCtrl = channelSink.AsyncProcessMessage(reqMsg, replySink); if (channelSink != CrossContextChannel.MessageSink) { Thread.CurrentThread.ReturnToContext(ref frame); } } return msgCtrl; }
[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); }