Merge pull request #1857 from slluis/fix-assembly-resolver
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Messaging / AsyncResult.cs
index 7aa60febd2aca813c2903a6e743f310286ca45b4..ff43f8dc0d0301c6df76aaf30b3e6e175dcdb352 100644 (file)
@@ -8,10 +8,7 @@
 //   Duncan Mak (duncan@ximian.com)
 //
 // (C) 2001 Ximian, Inc.  http://www.ximian.com
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 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;
        IntPtr data;
+       object object_data;
        bool sync_completed;
        bool completed;
        bool endinvoke_called;
        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 {
@@ -135,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;
        }
 
@@ -143,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);
                }
@@ -160,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 ();
 }
 }