Correctly report an exception in EndInvoke when BeginInvoke was called with a callbac...
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 5 Jun 2012 18:55:35 +0000 (15:55 -0300)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 5 Jun 2012 18:55:35 +0000 (15:55 -0300)
mono/metadata/threadpool.c
mono/tests/Makefile.am
mono/tests/async-with-cb-throws.cs [new file with mode: 0644]

index 089df523fa97d9ee2ba9d3d279bb989eec10fcb5..272bd1bcdb9afa586e94c672635d9b05b0ff53c7 100644 (file)
@@ -630,7 +630,7 @@ mono_async_invoke (ThreadPool *tp, MonoAsyncResult *ares)
        if (ac == NULL) {
                /* Fast path from ThreadPool.*QueueUserWorkItem */
                void *pa = ares->async_state;
-               mono_runtime_delegate_invoke (ares->async_delegate, &pa, &exc);
+               res = mono_runtime_delegate_invoke (ares->async_delegate, &pa, &exc);
        } else {
                MonoObject *cb_exc = NULL;
 
@@ -654,7 +654,6 @@ mono_async_invoke (ThreadPool *tp, MonoAsyncResult *ares)
                        void *pa = &ares;
                        cb_exc = NULL;
                        mono_runtime_invoke (ac->cb_method, ac->cb_target, pa, &cb_exc);
-                       MONO_OBJECT_SETREF (ac->msg, exc, cb_exc);
                        exc = cb_exc;
                } else {
                        exc = NULL;
index f1776e8458c0f16028557363972ba97fcd6aefec..c19568827a808a05414074e9725ef851f3f2339c 100644 (file)
@@ -382,7 +382,8 @@ BASE_TEST_CS_SRC=           \
        bug-1147.cs     \
        mono-path.cs    \
        bug-bxc-795.cs  \
-       bug-3903.cs
+       bug-3903.cs     \
+       async-with-cb-throws.cs
 
 TEST_CS_SRC_DIST=      \
        $(BASE_TEST_CS_SRC)     \
diff --git a/mono/tests/async-with-cb-throws.cs b/mono/tests/async-with-cb-throws.cs
new file mode 100644 (file)
index 0000000..52791d4
--- /dev/null
@@ -0,0 +1,55 @@
+using System;
+using System.Threading;
+using System.Runtime.InteropServices;
+
+class AsyncException : Exception {}
+
+class Tests
+{
+       delegate int SimpleDelegate (int a);
+
+       static int cb_state = 0;
+
+       static int async_func (int a)
+       {
+               Console.WriteLine ("async_func from delegate: " + a);
+               return 10;
+       }
+
+       static int async_func_throws (int a)
+       {
+               Console.WriteLine ("async_func_throws from delegate: " + a);
+               throw new AsyncException ();
+       }
+
+       static void async_callback (IAsyncResult ar)
+       {
+               Console.WriteLine ("Async Callback " + ar.AsyncState);
+               cb_state = 1;
+       }
+
+       static int Main ()
+       {
+               SimpleDelegate d = new SimpleDelegate (async_func_throws);
+               AsyncCallback ac = new AsyncCallback (async_callback);
+               string state1 = "STATE1";
+
+               // Call delegate via ThreadPool and check that the exception is rethrown correctly
+               IAsyncResult ar1 = d.BeginInvoke (1, ac, state1);
+
+               while (cb_state == 0)
+                       Thread.Sleep (0);
+
+               try {
+                       d.EndInvoke (ar1);
+                       Console.WriteLine ("NO EXCEPTION");
+                       return 1;
+               } catch (AsyncException) {
+                       Console.WriteLine ("received exception ... OK");
+                       return 0;
+               } catch (Exception e) {
+                       Console.WriteLine ("wrong exception {0}", e);
+                       return 3;
+               }
+       }
+}