X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Runtime.Remoting.Proxies%2FRealProxy.cs;h=de4b921cff8671dd29568107d49ca017960ae6a6;hb=f03a1b538bfb0d9be810688e8713731e122320b5;hp=b5d74d99e66f3b2383b90a1d47d7af0fac34fbb8;hpb=a097b5471761180c4aae2dab224ed9caeeae3e86;p=mono.git diff --git a/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs b/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs index b5d74d99e66..de4b921cff8 100644 --- a/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs +++ b/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs @@ -40,21 +40,29 @@ using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Contexts; using System.Runtime.CompilerServices; using System.Runtime.Serialization; - +using System.Runtime.InteropServices; +using System.Threading; namespace System.Runtime.Remoting.Proxies { +#pragma warning disable 169, 649 + [StructLayout (LayoutKind.Sequential)] internal class TransparentProxy { public RealProxy _rp; IntPtr _class; bool _custom_type_info; } +#pragma warning restore 169, 649 + [ComVisible (true)] + [StructLayout (LayoutKind.Sequential)] public abstract class RealProxy { // other classes visible to the runtime // derive from this class so keep these locals // in sync with the definition RealProxy // in object-internals.h + +#pragma warning disable 169, 414 #region Sync with object-internals.h Type class_to_proxy; internal Context _targetContext; @@ -62,9 +70,10 @@ namespace System.Runtime.Remoting.Proxies int _targetDomainId = -1; internal string _targetUri; internal Identity _objectIdentity; - Object _objTP; - object _stubData; + Object _objTP; + object _stubData; #endregion +#pragma warning restore 169, 414 protected RealProxy () { @@ -109,8 +118,8 @@ namespace System.Runtime.Remoting.Proxies public virtual void GetObjectData (SerializationInfo info, StreamingContext context) { - Object obj = GetTransparentProxy(); - RemotingServices.GetObjectData (obj, info, context); + Object obj = GetTransparentProxy(); + RemotingServices.GetObjectData (obj, info, context); } internal Identity ObjectIdentity @@ -154,13 +163,14 @@ namespace System.Runtime.Remoting.Proxies out object [] out_args) { MonoMethodMessage mMsg = (MonoMethodMessage) msg; - mMsg.LogicalCallContext = CallContext.CreateLogicalCallContext (true); + mMsg.LogicalCallContext = Thread.CurrentThread.GetMutableExecutionContext().LogicalCallContext; CallType call_type = mMsg.CallType; - bool is_remproxy = (rp as RemotingProxy) != null; + bool is_remproxy = (rp is RemotingProxy); + out_args = null; IMethodReturnMessage res_msg = null; - if (call_type == CallType.BeginInvoke) + if (call_type == CallType.BeginInvoke) // todo: set CallMessage in runtime instead mMsg.AsyncResult.CallMessage = mMsg; @@ -168,34 +178,49 @@ namespace System.Runtime.Remoting.Proxies res_msg = (IMethodReturnMessage)mMsg.AsyncResult.EndInvoke (); // Check for constructor msg - if (mMsg.MethodBase.IsConstructor) + if (mMsg.MethodBase.IsConstructor) { - if (is_remproxy) + if (is_remproxy) res_msg = (IMethodReturnMessage) (rp as RemotingProxy).ActivateRemoteObject ((IMethodMessage) msg); - else + else msg = new ConstructionCall (rp.GetProxiedType ()); } if (null == res_msg) { - res_msg = (IMethodReturnMessage)rp.Invoke (msg); - - // 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) - { + 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); + if (res_msg.LogicalCallContext != null && res_msg.LogicalCallContext.HasInfo) { + Thread.CurrentThread.GetMutableExecutionContext().LogicalCallContext.Merge (res_msg.LogicalCallContext); + } exc = res_msg.Exception; @@ -204,8 +229,12 @@ namespace System.Runtime.Remoting.Proxies out_args = null; throw exc.FixRemotingException(); } - else if (res_msg is IConstructionReturnMessage || mMsg.CallType == CallType.BeginInvoke) { - out_args = res_msg.OutArgs; + 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); @@ -214,7 +243,8 @@ namespace System.Runtime.Remoting.Proxies out_args = ProcessResponse (res_msg, mMsg.AsyncResult.CallMessage); } else { - out_args = res_msg.OutArgs; + if (out_args == null) + out_args = res_msg.OutArgs; } return res_msg.ReturnValue; @@ -244,6 +274,7 @@ namespace System.Runtime.Remoting.Proxies } [MonoTODO] + [ComVisible (true)] public IConstructionReturnMessage InitializeServerObject(IConstructionCallMessage ctorMsg) { throw new NotImplementedException();