Merge pull request #1857 from slluis/fix-assembly-resolver
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Messaging / AsyncResult.cs
index 540d0cc88dddc5a4ea3ee9958154092bf419f7e9..ff43f8dc0d0301c6df76aaf30b3e6e175dcdb352 100644 (file)
 using System;
 using System.Threading;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 
 namespace System.Runtime.Remoting.Messaging {
 
-public class AsyncResult : IAsyncResult, IMessageSink {
+[System.Runtime.InteropServices.ComVisible (true)]
+[StructLayout (LayoutKind.Sequential)]
+public class AsyncResult : IAsyncResult, IMessageSink, IThreadPoolWorkItem {
 
+#pragma warning disable 169, 414, 649
        object async_state;
        WaitHandle handle;
        object async_delegate;
@@ -49,16 +53,47 @@ public class AsyncResult : IAsyncResult, IMessageSink {
        object async_callback;
        ExecutionContext current;
        ExecutionContext original;
+       long add_time;
+#pragma warning restore 169, 414, 649
 
        // not part of MonoAsyncResult...
        MonoMethodMessage call_message;
+#pragma warning disable 0414
        IMessageCtrl message_ctrl;
+#pragma warning restore
        IMessage reply_message;
+       WaitCallback orig_cb;
        
        internal AsyncResult ()
        {
        }
-       
+
+       internal AsyncResult (WaitCallback cb, object state, bool capture_context)
+       {
+               orig_cb = cb;
+               if (capture_context) {
+                       var stackMark = default (StackCrawlMark);
+                       current = ExecutionContext.Capture (
+                               ref stackMark,
+                               ExecutionContext.CaptureOptions.IgnoreSyncCtx | ExecutionContext.CaptureOptions.OptimizeDefaultCase);
+                       cb = delegate {
+                               ExecutionContext.Run(current, ccb, this, true);
+                       };
+               }
+
+               async_state = state;
+               async_delegate = cb;
+       }
+
+       static internal ContextCallback ccb = new ContextCallback(WaitCallback_Context);
+
+       static private void WaitCallback_Context(Object state)
+       {
+               AsyncResult obj = (AsyncResult)state;
+               WaitCallback wc = obj.orig_cb as WaitCallback;
+               wc(obj.async_state);
+       }
+
        public virtual object AsyncState
        {
                get {
@@ -137,7 +172,12 @@ public class AsyncResult : IAsyncResult, IMessageSink {
 
        internal IMessage EndInvoke ()
        {
-               handle.WaitOne ();
+               lock (this) {
+                       if (completed)
+                               return reply_message;
+               }
+
+               AsyncWaitHandle.WaitOne ();
                return reply_message;
        }
 
@@ -145,11 +185,13 @@ public class AsyncResult : IAsyncResult, IMessageSink {
        {
                reply_message = msg;
 
-               completed = true;
-               NativeEventCalls.SetEvent_internal (handle.Handle);
+               lock (this) {
+                       completed = true;
+                       if (handle != null)
+                               ((ManualResetEvent) AsyncWaitHandle).Set ();
+               }
                
-               if (async_callback != null)
-               {
+               if (async_callback != null) {
                        AsyncCallback ac = (AsyncCallback) async_callback;
                        ac (this);
                }
@@ -162,5 +204,17 @@ public class AsyncResult : IAsyncResult, IMessageSink {
                get { return call_message; }
                set { call_message = value; }
        }
+
+       void IThreadPoolWorkItem.ExecuteWorkItem()
+       {
+               Invoke ();
+       }
+
+       void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae)
+       {
+       }
+
+       [MethodImplAttribute(MethodImplOptions.InternalCall)]
+       internal extern object Invoke ();
 }
 }