2010-05-21 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Fri, 21 May 2010 03:26:00 +0000 (03:26 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Fri, 21 May 2010 03:26:00 +0000 (03:26 -0000)
* HttpChannelListener.cs : do not accept more than one channel at a
  time. Remove extra fields. Add CancelAsync() implementation.

svn path=/trunk/mcs/; revision=157659

mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpChannelListener.cs

index 4bd100163e454131327239458f03f88f58f04c07..9b4c0e0f020c86a511393cf7548a94087908fd73 100755 (executable)
@@ -1,3 +1,8 @@
+2010-05-21  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * HttpChannelListener.cs : do not accept more than one channel at a
+         time. Remove extra fields. Add CancelAsync() implementation.
+
 2010-05-21  Atsushi Enomoto  <atsushi@ximian.com>
 
        * HttpListenerManager.cs : add a workaround for Func<>.BeginInvoke()
index e01c5e3f28958e70ab12272707b586be7c1c5758..6c187266522cd3d18fe112e73420a683c512c687 100644 (file)
@@ -36,6 +36,7 @@ using System.ServiceModel.Description;
 using System.ServiceModel.Dispatcher;
 using System.ServiceModel.Security;
 using System.Text;
+using System.Threading;
 
 namespace System.ServiceModel.Channels
 {
@@ -48,11 +49,9 @@ namespace System.ServiceModel.Channels
                {
                }
 
-               object creator_lock = new object ();
-
                protected override TChannel CreateChannel (TimeSpan timeout)
                {
-                       lock (creator_lock) {
+                       lock (ThisLock) {
                                return CreateChannelCore (timeout);
                        }
                }
@@ -102,7 +101,6 @@ namespace System.ServiceModel.Channels
        internal abstract class HttpChannelListenerBase<TChannel> : InternalChannelListenerBase<TChannel>, IChannelDispatcherBoundListener
                where TChannel : class, IChannel
        {
-               List<TChannel> channels = new List<TChannel> ();
                HttpListenerManager httpChannelManager;
 
                internal static HttpChannelListenerBase<TChannel>CurrentHttpChannelListener;
@@ -144,9 +142,18 @@ namespace System.ServiceModel.Channels
 
                public ServiceCredentialsSecurityTokenManager SecurityTokenManager { get; private set; }
 
+               ManualResetEvent accept_channel_handle = new ManualResetEvent (true);
+
                protected override TChannel OnAcceptChannel (TimeSpan timeout)
                {
-                       TChannel ch = CreateChannel (timeout);
+                       // HTTP channel listeners do not accept more than one channel at a time.
+                       DateTime start = DateTime.Now;
+                       accept_channel_handle.WaitOne (timeout - (DateTime.Now - start));
+                       accept_channel_handle.Reset ();
+                       TChannel ch = CreateChannel (timeout - (DateTime.Now - start));
+                       ch.Closed += delegate {
+                               accept_channel_handle.Set ();
+                       };
                        return ch;
                }
 
@@ -180,5 +187,15 @@ namespace System.ServiceModel.Channels
                        // http://blogs.msdn.com/drnick/archive/2006/03/22/557642.aspx
                        httpChannelManager.Stop (false);
                }
+
+               // immediately stop accepting channel.
+               public override bool CancelAsync (TimeSpan timeout)
+               {
+                       try {
+                               CurrentAsyncResult.AsyncWaitHandle.WaitOne (TimeSpan.Zero);
+                       } catch (TimeoutException) {
+                       }
+                       return true;
+               }
        }
 }