public static IMessage Activate (RemotingProxy proxy, ConstructionCall ctorCall) { IMessage response; ctorCall.SourceProxy = proxy; if (Thread.CurrentContext.HasExitSinks && !ctorCall.IsContextOk) response = Thread.CurrentContext.GetClientContextSinkChain ().SyncProcessMessage (ctorCall); else response = RemoteActivate (ctorCall); if (response is IConstructionReturnMessage && ((IConstructionReturnMessage)response).Exception == null && proxy.ObjectIdentity == null) { Identity identity = RemotingServices.GetMessageTargetIdentity (ctorCall); proxy.AttachIdentity (identity); } return response; }
/* this is called from unmanaged code */ internal static object PrivateInvoke (RealProxy rp, IMessage msg, out Exception exc, out object [] out_args) { MonoMethodMessage mMsg = (MonoMethodMessage) msg; mMsg.LogicalCallContext = CallContext.CreateLogicalCallContext (true); CallType call_type = mMsg.CallType; #if MOONLIGHT bool is_remproxy = false; #else bool is_remproxy = (rp is RemotingProxy); #endif out_args = null; IMethodReturnMessage res_msg = null; if (call_type == CallType.BeginInvoke) // todo: set CallMessage in runtime instead mMsg.AsyncResult.CallMessage = mMsg; if (call_type == CallType.EndInvoke) res_msg = (IMethodReturnMessage)mMsg.AsyncResult.EndInvoke (); // Check for constructor msg if (mMsg.MethodBase.IsConstructor) { #if !MOONLIGHT if (is_remproxy) res_msg = (IMethodReturnMessage) (rp as RemotingProxy).ActivateRemoteObject ((IMethodMessage) msg); else #endif msg = new ConstructionCall (rp.GetProxiedType ()); } if (null == res_msg) { bool failed = false; try { res_msg = (IMethodReturnMessage)rp.Invoke (msg); } catch (Exception ex) { failed = true; if (call_type == CallType.BeginInvoke) { // If async dispatch crashes, don't propagate the exception. // The exception will be raised when calling EndInvoke. mMsg.AsyncResult.SyncProcessMessage (new ReturnMessage (ex, msg as IMethodCallMessage)); res_msg = new ReturnMessage (null, null, 0, null, msg as IMethodCallMessage); } else throw; } // Note, from begining this code used AsyncResult.IsCompleted for // checking if it was a remoting or custom proxy, but in some // cases the remoting proxy finish before the call returns // causing this method to be called, therefore causing all kind of bugs. if ((!is_remproxy) && call_type == CallType.BeginInvoke && !failed) { IMessage asyncMsg = null; // allow calltype EndInvoke to finish asyncMsg = mMsg.AsyncResult.SyncProcessMessage (res_msg as IMessage); out_args = res_msg.OutArgs; res_msg = new ReturnMessage (asyncMsg, null, 0, null, res_msg as IMethodCallMessage); } } if (res_msg.LogicalCallContext != null && res_msg.LogicalCallContext.HasInfo) CallContext.UpdateCurrentCallContext (res_msg.LogicalCallContext); exc = res_msg.Exception; // todo: remove throw exception from the runtime invoke if (null != exc) { out_args = null; throw exc.FixRemotingException(); } else if (res_msg is IConstructionReturnMessage) { if (out_args == null) out_args = res_msg.OutArgs; } else if (mMsg.CallType == CallType.BeginInvoke) { // We don't have OutArgs in this case. } else if (mMsg.CallType == CallType.Sync) { out_args = ProcessResponse (res_msg, mMsg); } else if (mMsg.CallType == CallType.EndInvoke) { out_args = ProcessResponse (res_msg, mMsg.AsyncResult.CallMessage); } else { if (out_args == null) out_args = res_msg.OutArgs; } return res_msg.ReturnValue; }
internal RemotingProxy (Type type, string activationUrl, object[] activationAttributes) : base (type) { _hasEnvoySink = false; _ctorCall = ActivationServices.CreateConstructionCall (type, activationUrl, activationAttributes); }
public static ConstructionCall CreateConstructionCall (Type type, string activationUrl, object[] activationAttributes) { ConstructionCall ctorCall = new ConstructionCall (type); if (!type.IsContextful) { // Must be a remote activated object ctorCall.Activator = new AppDomainLevelActivator (activationUrl, ConstructionActivator); ctorCall.IsContextOk = false; // It'll be activated in a remote context return ctorCall; } // It is a CBO. Need collect context properties and // check if a new context is needed. IActivator activatorChain = ConstructionActivator; activatorChain = new ContextLevelActivator (activatorChain); ArrayList attributes = new ArrayList (); if (activationAttributes != null) attributes.AddRange (activationAttributes); bool isContextOk = (activationUrl == ChannelServices.CrossContextUrl); // Remote CBOs are always created in a new context Context currentContext = Threading.Thread.CurrentContext; if (isContextOk) { foreach (IContextAttribute attr in attributes) { if (!attr.IsContextOK (currentContext, ctorCall)) { isContextOk = false; break; } } } object[] typeAttributes = type.GetCustomAttributes (true); foreach (object attr in typeAttributes) { if (attr is IContextAttribute) { isContextOk = isContextOk && ((IContextAttribute)attr).IsContextOK (currentContext, ctorCall); attributes.Add (attr); } } if (!isContextOk) { // A new context is needed. Collect the context properties and chain // the context level activator. ctorCall.SetActivationAttributes (attributes.ToArray()); foreach (IContextAttribute attr in attributes) attr.GetPropertiesForNewContext (ctorCall); } if (activationUrl != ChannelServices.CrossContextUrl) activatorChain = new AppDomainLevelActivator (activationUrl, activatorChain); ctorCall.Activator = activatorChain; ctorCall.IsContextOk = isContextOk; return ctorCall; }
internal void AttachIdentity (Identity identity) { _objectIdentity = identity; if (identity is ClientActivatedIdentity) // It is a CBO { ClientActivatedIdentity cai = (ClientActivatedIdentity)identity; _targetContext = cai.Context; AttachServer (cai.GetServerObject ()); cai.SetClientProxy ((MarshalByRefObject) GetTransparentProxy()); } if (identity is ClientIdentity) { ((ClientIdentity)identity).ClientProxy = (MarshalByRefObject) GetTransparentProxy(); _targetUri = ((ClientIdentity)identity).TargetUri; } else _targetUri = identity.ObjectUri; if (_objectIdentity.EnvoySink != null) { _sink = _objectIdentity.EnvoySink; _hasEnvoySink = true; } else _sink = _objectIdentity.ChannelSink; _ctorCall = null; // Object already constructed }