New tests.
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / ReplyChannelBase.cs
index 80bf02ff27f1a1212a100036b8ce31e831233679..9bef1913b1aca6f9abe60f57db5666a13f36f5ad 100644 (file)
@@ -62,6 +62,10 @@ namespace System.ServiceModel.Channels
 
                ChannelListenerBase listener;
 
+               public ChannelListenerBase Listener {
+                       get { return listener; }
+               }
+
                public abstract EndpointAddress LocalAddress { get; }
 
                public override T GetProperty<T> ()
@@ -71,6 +75,7 @@ namespace System.ServiceModel.Channels
                        return base.GetProperty<T> ();
                }
 
+               // FIXME: this is wrong. Implement all of them in each channel.
                protected override void OnAbort ()
                {
                        OnClose (TimeSpan.Zero);
@@ -101,6 +106,7 @@ namespace System.ServiceModel.Channels
                delegate bool TryReceiveDelegate (TimeSpan timeout, out RequestContext context);
                TryReceiveDelegate try_recv_delegate;
 
+               object async_result_lock = new object ();
                protected Thread CurrentAsyncThread { get; private set; }
                protected IAsyncResult CurrentAsyncResult { get; private set; }
 
@@ -110,18 +116,26 @@ namespace System.ServiceModel.Channels
                                throw new InvalidOperationException ("Another async TryReceiveRequest operation is in progress");
                        if (try_recv_delegate == null)
                                try_recv_delegate = new TryReceiveDelegate (delegate (TimeSpan tout, out RequestContext ctx) {
-                                       if (CurrentAsyncResult != null)
-                                               CurrentAsyncThread = Thread.CurrentThread;
+                                       lock (async_result_lock) {
+                                               if (CurrentAsyncResult != null)
+                                                       CurrentAsyncThread = Thread.CurrentThread;
+                                       }
                                        try {
                                                return TryReceiveRequest (tout, out ctx);
                                        } finally {
-                                               CurrentAsyncResult = null;
-                                               CurrentAsyncThread = null;
+                                               lock (async_result_lock) {
+                                                       CurrentAsyncResult = null;
+                                                       CurrentAsyncThread = null;
+                                               }
                                        }
                                        });
                        RequestContext dummy;
-                       CurrentAsyncResult = try_recv_delegate.BeginInvoke (timeout, out dummy, callback, state);
-                       return CurrentAsyncResult;
+                       IAsyncResult result;
+                       lock (async_result_lock) {
+                               result = CurrentAsyncResult = try_recv_delegate.BeginInvoke (timeout, out dummy, callback, state);
+                       }
+                       // Note that at this point CurrentAsyncResult can be null here if delegate has run to completion
+                       return result;
                }
 
                public virtual bool EndTryReceiveRequest (IAsyncResult result)