X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Runtime.Remoting.Channels%2FChannelServices.cs;h=124d01a44294f656c7278191d65f4bf86d5acec5;hb=6e03e95d020719ce4c0e50ec6842d537be4a2746;hp=9a0ca54f5b7a1a34ad2bc3b203201c40738dd150;hpb=33dee9905bc11bf03d2c771462eea0e8223291d5;p=mono.git diff --git a/mcs/class/corlib/System.Runtime.Remoting.Channels/ChannelServices.cs b/mcs/class/corlib/System.Runtime.Remoting.Channels/ChannelServices.cs index 9a0ca54f5b7..124d01a4429 100644 --- a/mcs/class/corlib/System.Runtime.Remoting.Channels/ChannelServices.cs +++ b/mcs/class/corlib/System.Runtime.Remoting.Channels/ChannelServices.cs @@ -8,6 +8,29 @@ // 2002 (C) Copyright, Ximian, Inc. // +// +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + using System.Collections; using System.Reflection; using System.Runtime.Remoting; @@ -85,6 +108,7 @@ namespace System.Runtime.Remoting.Channels } // Not found. Try now creation delayed channels + RemotingConfiguration.LoadDefaultDelayedChannels (); foreach (IChannelSender sender in delayedClientChannels) { IMessageSink sink = CreateClientChannelSinkChain (sender, url, channelDataArray, out objectUri); @@ -130,13 +154,6 @@ namespace System.Runtime.Remoting.Channels } } - [MonoTODO] - public static IMessageCtrl AsyncDispatchMessage (IMessage msg, - IMessageSink replySink) - { - throw new NotImplementedException (); - } - public static IServerChannelSink CreateServerChannelSinkChain ( IServerChannelSinkProvider provider, IChannelReceiver channel) { @@ -148,13 +165,15 @@ namespace System.Runtime.Remoting.Channels return provider.CreateSink (channel); } - [MonoTODO] public static ServerProcessing DispatchMessage ( IServerChannelSinkStack sinkStack, IMessage msg, out IMessage replyMsg) { - // TODO: Async processing + if (msg == null) throw new ArgumentNullException ("msg"); + + // Async processing is not done here because there isn't any way + // to know if a message is to be dispatched sync or asynchronously. replyMsg = SyncDispatchMessage (msg); @@ -175,10 +194,30 @@ namespace System.Runtime.Remoting.Channels } } - [MonoTODO] public static IDictionary GetChannelSinkProperties (object obj) { - throw new NotImplementedException (); + if (!RemotingServices.IsTransparentProxy (obj)) + throw new ArgumentException ("obj must be a proxy","obj"); + + ClientIdentity ident = (ClientIdentity) RemotingServices.GetRealProxy (obj).ObjectIdentity; + IMessageSink sink = ident.ChannelSink; + ArrayList dics = new ArrayList (); + + while (sink != null && !(sink is IClientChannelSink)) + sink = sink.NextSink; + + if (sink == null) + return new Hashtable (); + + IClientChannelSink csink = sink as IClientChannelSink; + while (csink != null) + { + dics.Add (csink.Properties); + csink = csink.NextChannelSink; + } + + IDictionary[] adics = (IDictionary[]) dics.ToArray (typeof(IDictionary[])); + return new AggregateDictionary (adics); } public static string[] GetUrlsForObject (MarshalByRefObject obj) @@ -215,7 +254,7 @@ namespace System.Runtime.Remoting.Channels { IChannel regc = (IChannel) registeredChannels[n]; - if (regc.ChannelName == chnl.ChannelName) + if (regc.ChannelName == chnl.ChannelName && chnl.ChannelName != "") throw new RemotingException ("Channel " + regc.ChannelName + " already registered"); if (regc.ChannelPriority < chnl.ChannelPriority && pos==-1) @@ -319,13 +358,67 @@ namespace System.Runtime.Remoting.Channels } public static IMessage SyncDispatchMessage (IMessage msg) + { + IMessage ret = CheckIncomingMessage (msg); + if (ret != null) return CheckReturnMessage (msg, ret); + ret = _crossContextSink.SyncProcessMessage (msg); + return CheckReturnMessage (msg, ret); + } + + public static IMessageCtrl AsyncDispatchMessage (IMessage msg, IMessageSink replySink) + { + IMessage ret = CheckIncomingMessage (msg); + if (ret != null) { + replySink.SyncProcessMessage (CheckReturnMessage (msg, ret)); + return null; + } + +#if NET_1_1 + if (RemotingConfiguration.CustomErrorsEnabled (IsLocalCall (msg))) + replySink = new ExceptionFilterSink (msg, replySink); +#endif + + return _crossContextSink.AsyncProcessMessage (msg, replySink); + } + + static ReturnMessage CheckIncomingMessage (IMessage msg) { IMethodMessage call = (IMethodMessage)msg; - ServerIdentity identity = RemotingServices.GetIdentityForUri(call.Uri) as ServerIdentity; - if (identity == null) return new ReturnMessage (new RemotingException ("No receiver for uri " + call.Uri), (IMethodCallMessage) msg); + ServerIdentity identity = RemotingServices.GetIdentityForUri (call.Uri) as ServerIdentity; + + if (identity == null) + return new ReturnMessage (new RemotingException ("No receiver for uri " + call.Uri), (IMethodCallMessage) msg); RemotingServices.SetMessageTargetIdentity (msg, identity); - return _crossContextSink.SyncProcessMessage (msg); + return null; + } + + internal static IMessage CheckReturnMessage (IMessage callMsg, IMessage retMsg) + { +#if NET_1_1 + IMethodReturnMessage ret = retMsg as IMethodReturnMessage; + if (ret != null && ret.Exception != null) + { + if (RemotingConfiguration.CustomErrorsEnabled (IsLocalCall (callMsg))) + { + Exception ex = new Exception ("Server encountered an internal error. For more information, turn off customErrors in the server's .config file."); + retMsg = new MethodResponse (ex, (IMethodCallMessage)callMsg); + } + } +#endif + return retMsg; + } + + static bool IsLocalCall (IMessage callMsg) + { + return true; + +/* How can I know if a call is local?!? + + object isLocal = callMsg.Properties ["__isLocalCall"]; + if (isLocal == null) return false; + return (bool)isLocal; +*/ } public static void UnregisterChannel (IChannel chnl) @@ -335,14 +428,19 @@ namespace System.Runtime.Remoting.Channels lock (registeredChannels.SyncRoot) { - if (!registeredChannels.Contains ((object) chnl)) - throw new RemotingException (); - - registeredChannels.Remove ((object) chnl); + for (int n=0; n