/*
         *   Execute is called to complete a work item (sync or async).
         *   Execute assumes that the context is set correctly and the lock
         *   is taken (i.e. it makes no policy decisions)
         *
         *   It is called from the following 3 points:
         *       1. thread pool thread executing the callback for an async item
         *       2. calling thread executing the callback for a queued sync item
         *       3. calling thread directly calling Execute for a non-queued sync item
         */
        internal virtual void Execute()
        {
            // Execute should be called with the domain policy enforced
            // i.e. a Synchronization domain should be locked etc ...
            BCLDebug.Assert(IsSignaled(), "IsSignaled()");
            ContextTransitionFrame frame = new ContextTransitionFrame();

            Thread.CurrentThread.EnterContext(_ctx, ref frame);

            LogicalCallContext oldCallCtx = CallContext.SetLogicalCallContext(_callCtx);

            if (IsAsync())
            {
                //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] AsyncWork.Execute");
                _nextSink.AsyncProcessMessage(_reqMsg, _replySink);
            }
            else if (_nextSink != null)
            {
                //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] SyncWork.Execute");
                _replyMsg = _nextSink.SyncProcessMessage(_reqMsg);
            }
            CallContext.SetLogicalCallContext(oldCallCtx);

            Thread.CurrentThread.ReturnToContext(ref frame);
        }
예제 #2
0
        public virtual IMessage     SyncProcessMessage(IMessage msg)
        {
            // This gets called when the called object finishes the AsyncWork...

            // This is called irrespective of whether we delegated the initial
            // work to a thread pool thread or not. Quite likely it will be 
            // called on a user thread (i.e. a thread different from the 
            // forward call thread)
        
            // we just switch back to the old context before calling 
            // the next replySink
            IMessage retMsg = null;
            if (_replySink != null)
            {
                // This assert covers the common case (ThreadPool)
                // and checks that the reply thread for the async call 
                // indeed emerges from the server context.
                BCLDebug.Assert(
                    (_srvID == null)
                    || (_srvID.ServerContext == Thread.CurrentContext),
                    "Thread expected to be in the server context!");

                // Call the dynamic sinks to notify that the async call
                // has completed
                Thread.CurrentContext.NotifyDynamicSinks(
                    msg,    // this is the async reply
                    false,  // bCliSide
                    false,  // bStart
                    true,   // bAsync
                    true);  // bNotifyGlobals

                ContextTransitionFrame frame = new ContextTransitionFrame();
                Thread.CurrentThread.EnterContext(_oldCtx, ref frame);
                retMsg = _replySink.SyncProcessMessage(msg);
                Thread.CurrentThread.ReturnToContext(ref frame);
            }
            return retMsg;
        }
예제 #3
0
        } // AsyncProcessMessage


        internal static IMessageCtrl DoAsyncDispatch(IMessage reqMsg, IMessageSink replySink)
        {
            ServerIdentity srvID = GetServerIdentity(reqMsg);
            AsyncWorkItem workItem = null;
            
            // If active, notify the profiler that an asynchronous remoting message was received.
            if (RemotingServices.CORProfilerTrackRemotingAsync())
            {
                Guid g = Guid.Empty;

                if (RemotingServices.CORProfilerTrackRemotingCookie())
                {
                    Object obj = reqMsg.Properties["CORProfilerCookie"];
                    if (obj != null)
                        g = (Guid) obj;
                }

                RemotingServices.CORProfilerRemotingServerReceivingMessage(g, true);

                // 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 sent.  Upon invocation, it will notify the profiler
                    // then pass control on to the replySink passed in above.
                    IMessageSink profSink = 
                        new ServerAsyncReplyTerminatorSink(replySink);

                    // Replace the reply sink with our own
                    replySink = profSink;
                }
            }

            Context srvCtx = srvID.ServerContext;
            
            //if (srvCtx.IsThreadPoolAware)
            //{
                // this is the case when we do not queue the work item since the 
                // server context claims to be doing its own threading.

                Context oldCtx = Thread.CurrentContext;                     
                // change to server object context
                ContextTransitionFrame frame = new ContextTransitionFrame();
                Thread.CurrentThread.EnterContext(srvID.ServerContext, ref frame);

                // we use the work item just as our replySink in this case
                if (replySink != null)
                {
                     workItem = new AsyncWorkItem(replySink, oldCtx); 
                }
                Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: passing to ServerContextChain");
                // call the server context chain
                IMessageCtrl msgCtrl = 
                    srvID.ServerContext.GetServerContextChain().AsyncProcessMessage(reqMsg, (IMessageSink)workItem);
                Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: back from ServerContextChain");
                // chain back to the dispatch thread context
                Thread.CurrentThread.ReturnToContext(ref frame);
    
            //}

            return msgCtrl;
        } // DoDispatch
예제 #4
0
        public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink) 
        {
            Message.DebugOut("::::::::::::::::::::::::::: CrossContext Channel: Async call starting!!\n");
            // One way Async notifications may potentially pass a null reply sink.
            IMessage errMsg = ValidateMessage(reqMsg);
            IMessageCtrl msgCtrl=null;
            
            if (errMsg != null)
            {
                if (replySink!=null)
                {
                    replySink.SyncProcessMessage(errMsg);
                }
            }
            else
            {
                ServerIdentity srvID = GetServerIdentity(reqMsg);
                AsyncWorkItem workItem = null;
                
                // If active, notify the profiler that an asynchronous remoting message was received.
                if (RemotingServices.CORProfilerTrackRemotingAsync())
                {
                    Guid g = Guid.Empty;

                    if (RemotingServices.CORProfilerTrackRemotingCookie())
                    {
                        Object obj = reqMsg.Properties["CORProfilerCookie"];

                        if (obj != null)
                        {
                            g = (Guid) obj;
                        }
                    }

                    RemotingServices.CORProfilerRemotingServerReceivingMessage(g, true);

                    // 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 sent.  Upon invocation, it will notify the profiler
                        // then pass control on to the replySink passed in above.
                        IMessageSink profSink = new ServerAsyncReplyTerminatorSink(replySink);

                        // Replace the reply sink with our own
                        replySink = profSink;
                    }
                }

                Context srvCtx = srvID.ServerContext;
                if (srvCtx.IsThreadPoolAware)
                {
                    // this is the case when we do not queue the work item since the 
                    // server context claims to be doing its own threading.

                    Context oldCtx = Thread.CurrentContext;                     
                    // change to server object context
                    ContextTransitionFrame frame = new ContextTransitionFrame();
                    srvCtx = srvID.ServerContext;
                    Thread.CurrentThread.EnterContext(srvCtx, ref frame);

                    // we use the work item just as our replySink in this case
                    if (replySink != null)
                    {
                         workItem = new AsyncWorkItem(replySink, oldCtx); 
                    }

                    Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: passing to ServerContextChain");

                    srvCtx.NotifyDynamicSinks(
                                reqMsg,
                                false,  // bCliSide
                                true,   // bStart
                                true,   // bAsync
                                true);  // bNotifyGlobals

                    // call the server context chain
                    msgCtrl = 
                        srvCtx.GetServerContextChain().AsyncProcessMessage(
                            reqMsg, 
                            (IMessageSink)workItem);

                    // Note: for async calls, we will do the return notification
                    // for dynamic properties only when the async call 
                    // completes (i.e. when the replySink gets called) 

                    Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: back from ServerContextChain");

                    // chain back to the dispatch thread context
                    Thread.CurrentThread.ReturnToContext(ref frame);
    
                }
                else
                {
                    // This is the case where we take care of returning the calling
                    // thread asap by using the ThreadPool for completing the call.
                    
                    // we use a more elaborate WorkItem and delegate the work to the thread pool
                    workItem = new AsyncWorkItem(reqMsg, 
                                                replySink, 
                                                Thread.CurrentContext, 
                                                srvID);
    
                    WaitCallback threadFunc = new WaitCallback(workItem.FinishAsyncWork);
                    // Note: Dynamic sinks are notified in the threadFunc
                    ThreadPool.QueueUserWorkItem(threadFunc);
                    
                    msgCtrl = null;
                }
            }
    
            Message.DebugOut("::::::::::::::::::::::::::: CrossContext Channel: Async call returning!!\n");
            return msgCtrl;
        } // AsyncProcessMessage
예제 #5
0
        public virtual IMessage     SyncProcessMessage(IMessage reqMsg) 
        {
            IMessage replyMsg = null;
            try
            {
                Message.DebugOut("\n::::::::::::::::::::::::: CrossContext Channel: Sync call starting");
                IMessage errMsg = ValidateMessage(reqMsg);
                if (errMsg != null)
                {
                    return errMsg;
                }

                ServerIdentity srvID = GetServerIdentity(reqMsg);
                Message.DebugOut("Got Server identity \n");
                BCLDebug.Assert(null != srvID,"null != srvID");
                
                
                BCLDebug.Assert(null != srvID.ServerContext, "null != srvID.ServerContext");
                
                bool fEnteredContext = false;               
                ContextTransitionFrame frame = new ContextTransitionFrame();
                try
                {
                    Context srvCtx = srvID.ServerContext;
                    Thread.CurrentThread.EnterContext(srvCtx, ref frame);
                    fEnteredContext = true;
                    // If profiling of remoting is active, must tell the profiler that we have received
                    // a message.
                    if (RemotingServices.CORProfilerTrackRemoting())
                    {
                        Guid g = Guid.Empty;

                        if (RemotingServices.CORProfilerTrackRemotingCookie())
                        {
                            Object obj = reqMsg.Properties["CORProfilerCookie"];

                            if (obj != null)
                            {
                                g = (Guid) obj;
                            }
                        }

                        RemotingServices.CORProfilerRemotingServerReceivingMessage(g, false);
                    }
    
                    Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: passing to ServerContextChain");
                    
                    // Server side notifications for dynamic sinks are done
                    // in the x-context channel ... this is to maintain 
                    // symmetry of the point of notification between 
                    // the client and server context
                    srvCtx.NotifyDynamicSinks(
                                reqMsg,
                                false,  // bCliSide
                                true,   // bStart
                                false,  // bAsync
                                true);  // bNotifyGlobals

                    replyMsg = srvCtx.GetServerContextChain().SyncProcessMessage(reqMsg);
                    srvCtx.NotifyDynamicSinks(
                                replyMsg,
                                false,  // bCliSide
                                false,  // bStart
                                false,  // bAsync
                                true);  // bNotifyGlobals
            
                    Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: back from ServerContextChain");

                    // If profiling of remoting is active, must tell the profiler that we are sending a
                    // reply message.
                    if (RemotingServices.CORProfilerTrackRemoting())
                    {
                        Guid g;

                        RemotingServices.CORProfilerRemotingServerSendingReply(out g, false);

                        if (RemotingServices.CORProfilerTrackRemotingCookie())
                        {
                            replyMsg.Properties["CORProfilerCookie"] = g;
                        }
                    }
                }
                finally
                {
                    if(fEnteredContext)
                    {
                        Thread.CurrentThread.ReturnToContext(ref frame);
                    }
                }

            }
            catch(Exception e)
            {
                Message.DebugOut("Arrgh.. XCTXSink::throwing exception " + e + "\n");
                replyMsg = new ReturnMessage(e, (IMethodCallMessage)reqMsg);
                if (reqMsg!=null)
                {
                    ((ReturnMessage)replyMsg).SetLogicalCallContext(
                            (LogicalCallContext)
                            reqMsg.Properties[Message.CallContextKey]);
                }
            }
                
            Message.DebugOut("::::::::::::::::::::::::::: CrossContext Channel: Sync call returning!!\n");                         
            return replyMsg;
        }
예제 #6
0
            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)
            {
                ContextTransitionFrame frame = new ContextTransitionFrame();
                Thread.CurrentThread.EnterContext(_cliCtx, ref frame);

                // 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
                retMsg = _replySink.SyncProcessMessage(reqMsg);

                // return the thread to its earlier context
                Thread.CurrentThread.ReturnToContext(ref frame);
            }
            return retMsg;
            }
예제 #7
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;
        }
예제 #8
0
        } // CreateProxyForDomain

        internal static ObjRef CreateDataForDomain(int appDomainId, IntPtr defCtxID)
        {
            // This is a subroutine of CreateProxyForDomain
            // so we can segregate the object references
            // from different app domains into different frames.  This is
            // important for the app domain leak checking code.

            Message.DebugOut("Creating proxy for domain " + appDomainId + "\n");

            bool bNeedToReset = false;
            ObjRef objRef = null;

            ContextTransitionFrame frame = new ContextTransitionFrame();

            try
            {
                RegisterWellKnownChannels();

                // Set the current context to the given default Context
                // (of the new AppDomain).
                Thread.CurrentThread.EnterContextInternal(null, defCtxID, appDomainId, ref frame);
                bNeedToReset = true;

                // Ensure that the well known channels are registered in this domain too
                RegisterWellKnownChannels();            

                // Marshal the app domain object
                objRef = MarshalInternal(
                            Thread.CurrentContext.AppDomain,
                            null,
                            null);

                // Set the current context to the old context
                Thread.CurrentThread.ReturnToContext(ref frame);

                bNeedToReset = false;
            }
            finally
            {
                // Restore the old app domain
                if (bNeedToReset)
                {
                    Thread.CurrentThread.ReturnToContext(ref frame);
                }
            }

            return objRef;
        } // CreateDataForDomain
예제 #9
0
        // This function is called by ActivationServices in case
        // the activation needs to be within the same appdomain. These
        // are only for ContextBound types.
        // It is also called to do satisfy remote incoming requests from
        // the activation services. These could be for both ContextBound
        // and MarshalByRef types.
        internal static IConstructionReturnMessage DoCrossContextActivation(
            IConstructionCallMessage reqMsg)
        {           
            bool bCtxBound = reqMsg.ActivationType.IsContextful;
            ContextTransitionFrame frame = new ContextTransitionFrame();
            if (bCtxBound)
            {
                // If the type is context bound, we need to create 
                // the appropriate context and activate the object inside
                // it.

                // Create a new Context
                Context serverContext = new Context();              

                
                ArrayList list = (ArrayList) reqMsg.ContextProperties;
                Assembly asm = null;
                for (int i=0; i<list.Count; i++)
                {
                    IContextProperty prop = list[i] as IContextProperty;
                    if (null == prop)
                    {
                        throw new RemotingException(
                            Environment.GetResourceString(
                                "Remoting_Activation_BadAttribute"));
                    }
                    asm = prop.GetType().Assembly; 
                    // Make a security check to ensure that the context property
                    // is from a trusted assembly!
		    CheckForInfrastructurePermission(asm);

                    // This ensures that we don't try to add duplicate
                    // attributes (eg. type attributes common on both client
                    // and server end)
                    if (serverContext.GetProperty(prop.Name) == null)
                    {
                        serverContext.SetProperty(prop);
                    }
                }
                // No more property changes to the server context from here.
                serverContext.Freeze();

                // (This seems like an overkill but that is how it is spec-ed)
                // Ask each of the properties in the context we formed from
                // if it is happy with the current context.
                for (int i=0; i<list.Count;i++)
                {
                    if (!((IContextProperty)list[i]).IsNewContextOK(
                        serverContext))
                    {
                        throw new RemotingException(
                            Environment.GetResourceString(
                                "Remoting_Activation_PropertyUnhappy"));
                    }
                }

                // Change to server context
                Thread.CurrentThread.EnterContext(serverContext, ref frame);
            }

            // call the first sink in the server context chain
            IMethodReturnMessage retMsg =  (IMethodReturnMessage) 
                    Thread.CurrentContext.GetServerContextChain().SyncProcessMessage(reqMsg);

            // The return message may not be of type
            // IConstructionReturnMessage if an exception happens
            // in the sink chains.
            Exception e = null;
            IConstructionReturnMessage replyMsg = retMsg as IConstructionReturnMessage;
            if (null == replyMsg)
            {
                if (retMsg != null)
                {
                    e = retMsg.Exception;
                }
                else
                {
                    e = new RemotingException(
                            Environment.GetResourceString(
                                "Remoting_Activation_Failed"));

                }
                replyMsg = new ConstructorReturnMessage(e,null); 
                // We have created our own message ... transfer the callcontext
                // from the request message.
                ((ConstructorReturnMessage)replyMsg).SetLogicalCallContext(
                        (LogicalCallContext)
                        reqMsg.Properties[Message.CallContextKey]);
            }

            if (bCtxBound)
            {
                Thread.CurrentThread.ReturnToContext(ref frame);
            }

            return replyMsg;
        }
예제 #10
0
파일: thread.cs 프로젝트: ArildF/masters
 internal extern bool EnterContextInternal(Context ctx, IntPtr id, Int32 appDomainID, ref ContextTransitionFrame frame);
예제 #11
0
파일: thread.cs 프로젝트: ArildF/masters
 internal extern bool ReturnToContext(ref ContextTransitionFrame frame);
예제 #12
0
파일: thread.cs 프로젝트: ArildF/masters
 internal void EnterContext(Context newContext, ref ContextTransitionFrame frame)
 {
     EnterContextInternal(newContext, newContext.InternalContextID, 0, ref frame);
     // The newContext parameter is passed in just to keep GC from
     // collecting a new context when we are trying to enter it.
     // By the time this returns, the m_Context field in the managed
     // thread is already set to the newContext ... so from there on
     // the newContext is rooted.
     
     // EnterContextInternal is directly called by the X-AppDomain
     // channel since it only has the target context-id and not the
     // context object itself (since the latter is in another domain)
     // It is also called directly when we are bootstrapping a new
     // AppDomain w.r.t. remoting (in CreateProxyForDomain). In both
     // these cases, the newContext is null.
 }
예제 #13
0
        } // DoDispatch



        internal byte[] DoTransitionDispatch(
            byte[] reqStmBuff,  
            SmuggledMethodCallMessage smuggledMcm,
            out SmuggledMethodReturnMessage smuggledMrm)
        {    
            // Note: To be safe w.r.t. the app domain leak code, this frame
            // should have no non-agile references in it.

            ContextTransitionFrame frame = new ContextTransitionFrame();

            // change to server domain                  
            Thread.CurrentThread.EnterContextInternal(
                                    null, 
                                    _srvContextID, 
                                    _srvDomainID, 
                                    ref frame);

            byte[] retBuff = null;
            smuggledMrm = null;
            try
            {
                Message.DebugOut("#### : changed to Server Domain :: "+ (Thread.CurrentContext.InternalContextID).ToString("X") );

                retBuff = DoDispatch(reqStmBuff, smuggledMcm, out smuggledMrm);
            }
            catch (Exception e)
            {
                // This will catch exceptions thrown by the infrastructure,
                // Serialization/Deserialization etc
                // Those thrown by the server are already taken care of 
                // and encoded in the retMsg .. so we don't come here for 
                // that case.

                // We are in another appDomain, so we can't simply throw 
                // the exception object across. The following marshals it
                // into a serialized return message. 
                IMessage retMsg = 
                    new ReturnMessage(e, new ErrorMessage());
                //*********************** SERIALIZE RET-MSG ******************
                retBuff = CrossAppDomainSerializer.SerializeMessage(retMsg).GetBuffer(); 
                retMsg = null;
            }
            finally
            {                
                RemotingServices.LogRemotingStage(RemotingServices.SERVER_RET_SEND);
                Thread.CurrentThread.ReturnToContext(ref frame);
                Message.DebugOut("#### : changed back to Client Domain " + (Thread.CurrentContext.InternalContextID).ToString("X"));
            }

            // System.Diagnostics.Debugger.Break();
            return retBuff;
        } // DoTransitionDispatch
예제 #14
0
        /* package */
        internal virtual void FinishAsyncWork(Object stateIgnored)
        {
            // set to the server context
            ContextTransitionFrame frame = new ContextTransitionFrame();
            Context srvCtx = _srvID.ServerContext;
            Thread.CurrentThread.EnterContext(srvCtx, ref frame);

            LogicalCallContext threadPoolCallCtx = 
                CallContext.SetLogicalCallContext(_callCtx);

            // Call the server context chain Async. We provide workItem as our
            // replySink ... this will cause the replySink.ProcessMessage 
            // to switch back to the context of the original caller thread.
    
            // Call the dynamic sinks to notify that the async call
            // is starting
            srvCtx.NotifyDynamicSinks(
                _reqMsg,
                false,  // bCliSide
                true,   // bStart
                true,   // bAsync
                true);  // bNotifyGlobals

            IMessageCtrl ctrl = 
               srvCtx.GetServerContextChain().AsyncProcessMessage(
                    _reqMsg, 
                    (IMessageSink)this);

            // change back to the old context        
            CallContext.SetLogicalCallContext(threadPoolCallCtx);
            Thread.CurrentThread.ReturnToContext(ref frame);
        }    
예제 #15
0
        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
            {
                ChannelServices.NotifyProfiler(reqMsg, RemotingProfilerEvent.ClientSend);

                // 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);
                }
                replyMsg = channelSink.SyncProcessMessage(reqMsg);

                if (channelSink != CrossContextChannel.MessageSink)
                {
                    Thread.CurrentThread.ReturnToContext(ref frame);
                }

                ChannelServices.NotifyProfiler(replyMsg, RemotingProfilerEvent.ClientReceive);
            }
            
            
            if (bHasDynamicSinks)
            {
                ctx.NotifyDynamicSinks(reqMsg, 
                                   true,   // bCliSide
                                   false,  // bStart
                                   false,  // bAsync
                                   true);  // bNotifyGlobals 
            }
            
            return replyMsg;
        }
예제 #16
0
 /*
 *   Execute is called to complete a work item (sync or async).
 *   Execute assumes that the context is set correctly and the lock
 *   is taken (i.e. it makes no policy decisions)
 * 
 *   It is called from the following 3 points:
 *       1. thread pool thread executing the callback for an async item
 *       2. calling thread executing the callback for a queued sync item
 *       3. calling thread directly calling Execute for a non-queued sync item
 */
 internal virtual void Execute()
 {
     // Execute should be called with the domain policy enforced
     // i.e. a Synchronization domain should be locked etc ...
     BCLDebug.Assert(IsSignaled(),"IsSignaled()");
     ContextTransitionFrame frame = new ContextTransitionFrame();
     Thread.CurrentThread.EnterContext(_ctx, ref frame);            
  
     LogicalCallContext oldCallCtx = CallContext.SetLogicalCallContext(_callCtx);
     if (IsAsync())
     {
         //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] AsyncWork.Execute");
         _nextSink.AsyncProcessMessage(_reqMsg, _replySink);            
     }
     else if (_nextSink != null)
     {
         //DBGConsole.WriteLine(Thread.CurrentThread.GetHashCode()+"] SyncWork.Execute");               
         _replyMsg = _nextSink.SyncProcessMessage(_reqMsg);                
     }                        
     CallContext.SetLogicalCallContext(oldCallCtx);
     
     Thread.CurrentThread.ReturnToContext(ref frame);
 }
예제 #17
0
파일: appdomain.cs 프로젝트: ArildF/masters
        private static void InternalRemotelySetupRemoteDomain(IntPtr contextId, 
                                                              int domainId,
                                                              String friendlyName,
                                                              AppDomainSetup setup,
                                                              IntPtr parentSecurityDescriptor,
                                                              char[] serProvidedEvidence,
                                                              char[] serCreatorEvidence,
                                                              byte[] serializedEvidence)
        {
            bool bNeedToReset = false;

            ContextTransitionFrame frame = new ContextTransitionFrame();

            try {
                // Set the current context to the given default Context
                // (of the new AppDomain).
                Thread.CurrentThread.EnterContextInternal(null, contextId, domainId, ref frame);
                bNeedToReset = true;

                InternalRemotelySetupRemoteDomainHelper(friendlyName, setup, parentSecurityDescriptor,
                                                        serProvidedEvidence, serCreatorEvidence, serializedEvidence);

                // Set the current context to the old context
                Thread.CurrentThread.ReturnToContext(ref frame);
                bNeedToReset = false;
            }
            finally {
                // Restore the old app domain
                if (bNeedToReset)
                    Thread.CurrentThread.ReturnToContext(ref frame);
            }    
        } // InternalSetupRemoteDomain