Inheritance: IMessageSink
        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;
        }
Example #3
0
        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);
        }