We need you! We're working hard on the next version of Developer Fusion -
Let us know what you think we should be up to!
- namespace System.Runtime.Remoting.Channels
- {
-
- using System;
- using System.Collections;
- using System.Threading;
- using System.Runtime.Remoting;
- using System.Runtime.Remoting.Contexts;
- using System.Runtime.Remoting.Messaging;
- using System.Runtime.Serialization;
-
-
-
- internal class CrossContextChannel : InternalSink, IMessageSink
- {
- private const string _channelName = "XCTX";
- private const int _channelCapability = 0;
- private const string _channelURI = "XCTX_URI";
-
- private static CrossContextChannel messageSink {
- get { return Thread.GetDomain().RemotingData.ChannelServicesData.xctxmessageSink; }
- set { Thread.GetDomain().RemotingData.ChannelServicesData.xctxmessageSink = value; }
- }
-
- private static object staticSyncObject = new object();
- private static InternalCrossContextDelegate s_xctxDel = new InternalCrossContextDelegate(SyncProcessMessageCallback);
-
- static internal IMessageSink MessageSink {
- get {
- if (messageSink == null) {
- CrossContextChannel tmpSink = new CrossContextChannel();
-
- lock (staticSyncObject) {
- if (messageSink == null) {
- messageSink = tmpSink;
- }
- }
-
- }
- return messageSink;
- }
- }
-
- static internal object SyncProcessMessageCallback(object[] args)
- {
- IMessage reqMsg = args[0] as IMessage;
- Context srvCtx = args[1] as Context;
- IMessage replyMsg = null;
-
-
-
- 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");
-
-
-
-
-
-
-
-
- srvCtx.NotifyDynamicSinks(reqMsg, false, true, false, true);
-
- replyMsg = srvCtx.GetServerContextChain().SyncProcessMessage(reqMsg);
-
-
-
- srvCtx.NotifyDynamicSinks(replyMsg, false, false, false, true);
-
- Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: back from ServerContextChain");
-
-
-
- if (RemotingServices.CORProfilerTrackRemoting()) {
- Guid g;
-
- RemotingServices.CORProfilerRemotingServerSendingReply(out g, false);
-
- if (RemotingServices.CORProfilerTrackRemotingCookie()) {
- replyMsg.Properties["CORProfilerCookie"] = g;
- }
- }
- return replyMsg;
- }
-
- public virtual IMessage SyncProcessMessage(IMessage reqMsg)
- {
- object[] args = new object[] {null, null};
- 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");
-
- args[0] = reqMsg;
- args[1] = srvID.ServerContext;
- replyMsg = (IMessage)Thread.CurrentThread.InternalCrossContextCallback(srvID.ServerContext, s_xctxDel, args);
- }
- 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;
- }
-
- static internal object AsyncProcessMessageCallback(object[] args)
- {
- AsyncWorkItem workItem = null;
-
- IMessage reqMsg = (IMessage)args[0];
- IMessageSink replySink = (IMessageSink)args[1];
- Context oldCtx = (Context)args[2];
- Context srvCtx = (Context)args[3];
- IMessageCtrl msgCtrl = null;
-
-
- if (replySink != null) {
- workItem = new AsyncWorkItem(replySink, oldCtx);
- }
-
- Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: passing to ServerContextChain");
-
-
-
-
- srvCtx.NotifyDynamicSinks(reqMsg, false, true, true, true);
-
-
- msgCtrl = srvCtx.GetServerContextChain().AsyncProcessMessage(reqMsg, (IMessageSink)workItem);
-
-
-
-
-
- Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: back from ServerContextChain");
-
- return msgCtrl;
- }
-
- public virtual IMessageCtrl AsyncProcessMessage(IMessage reqMsg, IMessageSink replySink)
- {
- Message.DebugOut("::::::::::::::::::::::::::: CrossContext Channel: Async call starting!!\n");
-
- IMessage errMsg = ValidateMessage(reqMsg);
-
- object[] args = new object[] {null, null, null, null};
-
- IMessageCtrl msgCtrl = null;
- if (errMsg != null) {
- if (replySink != null) {
- replySink.SyncProcessMessage(errMsg);
- }
- }
- else {
- ServerIdentity srvID = GetServerIdentity(reqMsg);
-
-
- 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);
-
-
- if (replySink != null) {
-
-
-
- IMessageSink profSink = new ServerAsyncReplyTerminatorSink(replySink);
-
-
- replySink = profSink;
- }
- }
-
- Context srvCtx = srvID.ServerContext;
- if (srvCtx.IsThreadPoolAware) {
-
-
-
- args[0] = reqMsg;
- args[1] = replySink;
- args[2] = Thread.CurrentContext;
- args[3] = srvCtx;
-
- InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(AsyncProcessMessageCallback);
-
- msgCtrl = (IMessageCtrl)Thread.CurrentThread.InternalCrossContextCallback(srvCtx, xctxDel, args);
- }
- else {
- AsyncWorkItem workItem = null;
-
-
-
-
-
- workItem = new AsyncWorkItem(reqMsg, replySink, Thread.CurrentContext, srvID);
-
- WaitCallback threadFunc = new WaitCallback(workItem.FinishAsyncWork);
-
- ThreadPool.QueueUserWorkItem(threadFunc);
- }
- }
-
- Message.DebugOut("::::::::::::::::::::::::::: CrossContext Channel: Async call returning!!\n");
- return msgCtrl;
- }
-
- static internal object DoAsyncDispatchCallback(object[] args)
- {
- AsyncWorkItem workItem = null;
-
- IMessage reqMsg = (IMessage)args[0];
- IMessageSink replySink = (IMessageSink)args[1];
- Context oldCtx = (Context)args[2];
- Context srvCtx = (Context)args[3];
- IMessageCtrl msgCtrl = null;
-
-
-
- if (replySink != null) {
- workItem = new AsyncWorkItem(replySink, oldCtx);
- }
- Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: passing to ServerContextChain");
-
- msgCtrl = srvCtx.GetServerContextChain().AsyncProcessMessage(reqMsg, (IMessageSink)workItem);
- Message.DebugOut("::::::::::::::::::::::::: CrossContext Channel: back from ServerContextChain");
-
- return msgCtrl;
- }
-
-
- static internal IMessageCtrl DoAsyncDispatch(IMessage reqMsg, IMessageSink replySink)
- {
- object[] args = new object[] {null, null, null, null};
-
- ServerIdentity srvID = GetServerIdentity(reqMsg);
-
-
- 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);
-
-
- if (replySink != null) {
-
-
-
- IMessageSink profSink = new ServerAsyncReplyTerminatorSink(replySink);
-
-
- replySink = profSink;
- }
- }
-
- IMessageCtrl msgCtrl = null;
- Context srvCtx = srvID.ServerContext;
-
-
-
-
-
-
- args[0] = reqMsg;
- args[1] = replySink;
- args[2] = Thread.CurrentContext;
- args[3] = srvCtx;
-
- InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(DoAsyncDispatchCallback);
-
- msgCtrl = (IMessageCtrl)Thread.CurrentThread.InternalCrossContextCallback(srvCtx, xctxDel, args);
-
-
-
- return msgCtrl;
- }
-
- public IMessageSink NextSink {
- get { return null; }
- }
- }
-
-
- internal class AsyncWorkItem : IMessageSink
- {
-
- private IMessageSink _replySink;
-
-
- private ServerIdentity _srvID;
-
-
- private Context _oldCtx;
-
- private LogicalCallContext _callCtx;
-
-
- private IMessage _reqMsg;
-
-
- internal AsyncWorkItem(IMessageSink replySink, Context oldCtx) : this(null, replySink, oldCtx, null)
- {
- }
-
- internal AsyncWorkItem(IMessage reqMsg, IMessageSink replySink, Context oldCtx, ServerIdentity srvID)
- {
- _reqMsg = reqMsg;
- _replySink = replySink;
- _oldCtx = oldCtx;
- _callCtx = CallContext.GetLogicalCallContext();
- _srvID = srvID;
- }
-
- static internal object SyncProcessMessageCallback(object[] args)
- {
- IMessageSink replySink = (IMessageSink)args[0];
- IMessage msg = (IMessage)args[1];
-
- return replySink.SyncProcessMessage(msg);
- }
-
- public virtual IMessage SyncProcessMessage(IMessage msg)
- {
-
-
-
-
-
-
-
-
-
-
- IMessage retMsg = null;
-
- if (_replySink != null) {
-
-
-
- BCLDebug.Assert((_srvID == null) || (_srvID.ServerContext == Thread.CurrentContext), "Thread expected to be in the server context!");
-
-
-
-
-
-
-
- Thread.CurrentContext.NotifyDynamicSinks(msg, false, false, true, true);
-
- object[] args = new object[] {_replySink, msg};
-
- InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(SyncProcessMessageCallback);
-
- retMsg = (IMessage)Thread.CurrentThread.InternalCrossContextCallback(_oldCtx, xctxDel, args);
- }
- return retMsg;
- }
-
- public virtual IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
- {
-
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_Method"));
- }
-
- public IMessageSink NextSink {
- get { return _replySink; }
- }
-
- static internal object FinishAsyncWorkCallback(object[] args)
- {
- AsyncWorkItem This = (AsyncWorkItem)args[0];
- Context srvCtx = This._srvID.ServerContext;
-
- LogicalCallContext threadPoolCallCtx = CallContext.SetLogicalCallContext(This._callCtx);
-
-
-
-
-
-
-
-
-
-
- srvCtx.NotifyDynamicSinks(This._reqMsg, false, true, true, true);
-
- IMessageCtrl ctrl = srvCtx.GetServerContextChain().AsyncProcessMessage(This._reqMsg, (IMessageSink)This);
-
-
- CallContext.SetLogicalCallContext(threadPoolCallCtx);
-
- return null;
- }
-
-
- internal virtual void FinishAsyncWork(object stateIgnored)
- {
- InternalCrossContextDelegate xctxDel = new InternalCrossContextDelegate(FinishAsyncWorkCallback);
-
- object[] args = new object[] {this};
-
- Thread.CurrentThread.InternalCrossContextCallback(_srvID.ServerContext, xctxDel, args);
- }
- }
- }