Merge pull request #1225 from strawd/bug22307
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Dispatcher / ChannelDispatcher.cs
index 13e91bf31c96959062e7ed262600a55c77e0089f..65b5c8cf38ae6913b2482b54609ecc8ee45064e4 100644 (file)
@@ -35,6 +35,9 @@ using System.Threading;
 using System.Transactions;
 using System.ServiceModel;
 using System.ServiceModel.Description;
+using System.Net.Sockets;
+using System.Xml;
+using System.IO;
 
 namespace System.ServiceModel.Dispatcher
 {
@@ -375,8 +378,7 @@ namespace System.ServiceModel.Dispatcher
                                        try {
                                                ChannelAccepted (r.EndAcceptChannel (result));
                                        } catch (Exception ex) {
-                                               Console.WriteLine ("Exception during finishing channel acceptance.");
-                                               Console.WriteLine (ex);
+                                               Logger.Error ("Exception during finishing channel acceptance.", ex);
                                                creator_handle.Set ();
                                        }
                                };
@@ -384,8 +386,7 @@ namespace System.ServiceModel.Dispatcher
                                        try {
                                                return r.BeginAcceptChannel (callback, null);
                                        } catch (Exception ex) {
-                                               Console.WriteLine ("Exception during accepting channel.");
-                                               Console.WriteLine (ex);
+                                               Logger.Error ("Exception during accepting channel.", ex);
                                                throw;
                                        }
                                };
@@ -421,8 +422,7 @@ namespace System.ServiceModel.Dispatcher
                                        stop_handle = null;
                                }
                                if (owner.Listener.State != CommunicationState.Closed) {
-                                       // FIXME: log it
-                                       Console.WriteLine ("Channel listener '{0}' is not closed. Aborting.", owner.Listener.GetType ());
+                                       Logger.Warning (String.Format ("Channel listener '{0}' is not closed. Aborting.", owner.Listener.GetType ()));
                                        owner.Listener.Abort ();
                                }
                                if (loop_thread != null && loop_thread.IsAlive)
@@ -447,7 +447,7 @@ namespace System.ServiceModel.Dispatcher
                        {
                                channels.Remove (ch); // zonbie, if exists
                                var ich = ch as ISessionChannel<IInputSession>;
-                               List<IChannel> l;
+                               
                                if (ich != null && ich.Session != null)
                                        sessions.Remove (ich.Session);
                        }
@@ -455,14 +455,17 @@ namespace System.ServiceModel.Dispatcher
                        public void CloseInput ()
                        {
                                foreach (var ch in channels.ToArray ()) {
-                                       if (ch.State == CommunicationState.Closed)
-                                               RemoveChannel (ch);
+                                       if (ch.State == CommunicationState.Closed) {
+                                               lock (channels) {
+                                                       RemoveChannel (ch);
+                                               }
+                                       }
                                        else {
                                                try {
                                                        ch.Close (close_timeout - (DateTime.Now - close_started));
                                                } catch (Exception ex) {
                                                        // FIXME: log it.
-                                                       Console.WriteLine (ex);
+                                                       Logger.Error (String.Format ("Exception on closing channel ({0})", ch.GetType ()), ex);
                                                        ch.Abort ();
                                                }
                                        }
@@ -474,9 +477,7 @@ namespace System.ServiceModel.Dispatcher
                                try {
                                        LoopCore ();
                                } catch (Exception ex) {
-                                       // FIXME: log it
-                                       Console.WriteLine ("ListenerLoopManager caught an exception inside dispatcher loop, which is likely thrown by the channel listener {0}", owner.Listener);
-                                       Console.WriteLine (ex);
+                                       Logger.Error (String.Format ("ListenerLoopManager caught an exception inside dispatcher loop, which is likely thrown by the channel listener {0}", owner.Listener), ex);
                                } finally {
                                        if (stop_handle != null)
                                                stop_handle.Set ();
@@ -504,6 +505,8 @@ namespace System.ServiceModel.Dispatcher
                                }
                                try {
                                        owner.Listener.Close ();
+                               } catch (Exception ex) {
+                                       Logger.Error (String.Format ("Exception while closing IChannelListener ({0})", owner.Listener.GetType ()), ex);
                                } finally {
                                        // make sure to close both listener and channels.
                                        owner.CloseInput ();
@@ -584,10 +587,14 @@ namespace System.ServiceModel.Dispatcher
                        {
                                Message msg;
                                var input = (IInputChannel) result.AsyncState;
-                               if (input.EndTryReceive (result, out msg))
-                                       ProcessInput (input, msg);
-                               else
+                               try {
+                                       if (input.EndTryReceive (result, out msg))
+                                               ProcessInput (input, msg);
+                                       else
+                                               input.Close ();
+                               } catch (ObjectDisposedException) {
                                        input.Close ();
+                               }
                        }
 
                        void ProcessRequest (IReplyChannel reply, RequestContext rc)
@@ -595,16 +602,16 @@ namespace System.ServiceModel.Dispatcher
                                try {
                                        var req = rc.RequestMessage;
                                        var ed = FindEndpointDispatcher (req);
-                                       // FIXME: explicitly dispose this.
-//                                     using (var processor = new InputOrReplyRequestProcessor (ed.DispatchRuntime, reply))
-                                       var processor = new InputOrReplyRequestProcessor (ed.DispatchRuntime, reply);
-                                               processor.ProcessReply (rc);
+                                       new InputOrReplyRequestProcessor (ed.DispatchRuntime, reply).ProcessReply (rc);
                                } catch (Exception ex) {
                                        Message res;
                                        if (ProcessErrorWithHandlers (reply, ex, out res))
                                                return;
 
-                                       rc.Reply (res);
+                                       if ((!(ex is SocketException)) && 
+                                           (!(ex is XmlException)) &&
+                                           (!(ex is IOException)))
+                                               rc.Reply (res);
                                        
                                        reply.Close (owner.DefaultCloseTimeout); // close the channel
                                } finally {
@@ -624,8 +631,7 @@ namespace System.ServiceModel.Dispatcher
                                        if (eh.HandleError (ex))
                                                return true; // error is handled appropriately.
 
-                               // FIXME: log it.
-                               Console.WriteLine (ex);
+                               Logger.Error ("An error occured, to be handled", ex);
 
                                foreach (var eh in owner.ErrorHandlers)
                                        eh.ProvideFault (ex, owner.MessageVersion, ref res);
@@ -643,10 +649,7 @@ namespace System.ServiceModel.Dispatcher
                                try {
                                        EndpointDispatcher candidate = null;
                                        candidate = FindEndpointDispatcher (message);
-                                       // FIXME: explicitly dispose this.
-//                                     using (var processor = new InputOrReplyRequestProcessor (candidate.DispatchRuntime, input))
-                                       var processor = new InputOrReplyRequestProcessor (candidate.DispatchRuntime, input);
-                                               processor.ProcessInput (message);
+                                       new InputOrReplyRequestProcessor (candidate.DispatchRuntime, input).ProcessInput (message);
                                }
                                catch (Exception ex) {
                                        Message dummy;