[System.ServiceModel] Don't use DateTime.Now for measuring elapsed time
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / PeerChannelListener.cs
index fdfea9ddfdd53002d0f24b3ea8bf00e8669d79b1..39303073f964c48c950304ef7dc5ab60313c6595 100755 (executable)
@@ -34,88 +34,65 @@ using System.ServiceModel;
 using System.ServiceModel.Description;
 using System.ServiceModel.Security;
 using System.Text;
+using System.Threading;
 
 namespace System.ServiceModel.Channels
 {
-       internal class PeerChannelListener<TChannel> : ChannelListenerBase<TChannel>
+       internal class PeerChannelListener<TChannel> : InternalChannelListenerBase<TChannel>, IPeerChannelManager
                where TChannel : class, IChannel
        {
                PeerTransportBindingElement source;
                BindingContext context;
-               Uri listen_uri;
-               List<IChannel> channels = new List<IChannel> ();
-               MessageEncoder encoder;
+               TChannel channel;
+               AutoResetEvent accept_handle = new AutoResetEvent (false);
 
                public PeerChannelListener (PeerTransportBindingElement source,
                        BindingContext context)
-                       : base (context.Binding)
+                       : base (context)
                {
-                       // FIXME: consider ListenUriMode
-                       // FIXME: there should be some way to post-provide Uri in case of null listenerUri in context.
-                       listen_uri = context.ListenUriBaseAddress != null ?
-                               new Uri (context.ListenUriBaseAddress, context.ListenUriRelativeAddress) : null;
-                       foreach (BindingElement be in context.RemainingBindingElements) {
+                       this.source = source;
+                       foreach (BindingElement be in context.Binding.Elements) {
                                MessageEncodingBindingElement mbe = be as MessageEncodingBindingElement;
                                if (mbe != null) {
-                                       encoder = mbe.CreateMessageEncoderFactory ().Encoder;
+                                       MessageEncoder = CreateEncoder<TChannel> (mbe);
                                        break;
                                }
                        }
-                       if (encoder == null)
-                               encoder = new TextMessageEncoder (MessageVersion.Default, Encoding.UTF8);
+                       if (MessageEncoder == null)
+                               MessageEncoder = new BinaryMessageEncoder ();
                }
 
                public PeerResolver Resolver { get; set; }
 
-               public MessageEncoder MessageEncoder {
-                       get { return encoder; }
-               }
-
-               public override Uri Uri {
-                       get { return listen_uri; }
+               public PeerTransportBindingElement Source {
+                       get { return source; }
                }
 
                protected override TChannel OnAcceptChannel (TimeSpan timeout)
                {
-                       TChannel ch = PopulateChannel (timeout);
-                       channels.Add (ch);
-                       return ch;
+                       DateTime start = DateTime.UtcNow;
+                       if (channel != null)
+                               if (!accept_handle.WaitOne (timeout))
+                                       throw new TimeoutException ();
+                       channel = PopulateChannel (timeout - (DateTime.UtcNow - start));
+                       ((CommunicationObject) (object) channel).Closed += delegate {
+                               this.channel = null;
+                               accept_handle.Set ();
+                               };
+                       return channel;
                }
 
                TChannel PopulateChannel (TimeSpan timeout)
                {
                        if (typeof (TChannel) == typeof (IInputChannel))
-                               return (TChannel) (object) new PeerInputChannel ((PeerChannelListener<IInputChannel>) (object) this, timeout);
+                               return (TChannel) (object) new PeerDuplexChannel (this);
                        // FIXME: handle timeout somehow.
                        if (typeof (TChannel) == typeof (IDuplexChannel))
-                               return (TChannel) (object) new PeerDuplexChannel ((PeerChannelListener<IDuplexChannel>) (object) this);
+                               return (TChannel) (object) new PeerDuplexChannel (this);
 
                        throw new InvalidOperationException (String.Format ("Not supported channel '{0}' (mono bug; it is incorrectly allowed at construction time)", typeof (TChannel)));
                }
 
-               protected override IAsyncResult OnBeginAcceptChannel (
-                       TimeSpan timeout, AsyncCallback callback,
-                       object asyncState)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override TChannel OnEndAcceptChannel (IAsyncResult result)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override IAsyncResult OnBeginWaitForChannel (
-                       TimeSpan timeout, AsyncCallback callback, object state)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override bool OnEndWaitForChannel (IAsyncResult result)
-               {
-                       throw new NotImplementedException ();
-               }
-
                protected override bool OnWaitForChannel (TimeSpan timeout)
                {
                        throw new NotImplementedException ();
@@ -123,45 +100,18 @@ namespace System.ServiceModel.Channels
 
                protected override void OnOpen (TimeSpan timeout)
                {
-                       throw new NotImplementedException ();
-               }
-
-               protected override IAsyncResult OnBeginOpen (TimeSpan timeout,
-                       AsyncCallback callback, object state)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override void OnEndOpen (IAsyncResult result)
-               {
-                       throw new NotImplementedException ();
                }
 
                protected override void OnClose (TimeSpan timeout)
                {
-                       if (ServiceHostingEnvironment.InAspNet)
-                               return;
-
-                       foreach (TChannel ch in channels)
-                               ch.Close(timeout);
-               }
-
-               [MonoTODO]
-               protected override IAsyncResult OnBeginClose (TimeSpan timeout,
-                       AsyncCallback callback, object state)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               protected override void OnEndClose (IAsyncResult result)
-               {
-                       throw new NotImplementedException ();
+                       if (channel != null)
+                               channel.Close (timeout);
                }
 
-               [MonoTODO ("find out what to do here.")]
                protected override void OnAbort ()
                {
+                       if (channel != null)
+                               channel.Abort ();
                }
        }
 }