Merge pull request #2802 from BrzVlad/feature-evacuation-opt2
[mono.git] / mono / metadata / monitor.c
index 23f53d0dc5ecfa18e3e9ba4b9939133c1a0cc281..45c13be4e0f780ed511c327c5c9925ff97626e36 100644 (file)
@@ -6,6 +6,7 @@
  *
  * Copyright 2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <config.h>
@@ -896,7 +897,7 @@ retry_contended:
                 * We have to obey a stop/suspend request even if 
                 * allow_interruption is FALSE to avoid hangs at shutdown.
                 */
-               if (!mono_thread_test_state (mono_thread_internal_current (), (MonoThreadState)(ThreadState_StopRequested | ThreadState_SuspendRequested))) {
+               if (!mono_thread_test_state (mono_thread_internal_current (), (MonoThreadState)(ThreadState_StopRequested | ThreadState_SuspendRequested | ThreadState_AbortRequested))) {
                        if (ms != INFINITE) {
                                now = mono_msec_ticks ();
                                if (now < then) {
@@ -1082,8 +1083,13 @@ ves_icall_System_Threading_Monitor_Monitor_try_enter (MonoObject *obj, guint32 m
 
        do {
                res = mono_monitor_try_enter_internal (obj, ms, TRUE);
-               if (res == -1)
-                       mono_thread_interruption_checkpoint ();
+               if (res == -1) {
+                       MonoException *exc = mono_thread_interruption_checkpoint ();
+                       if (exc) {
+                               mono_set_pending_exception (exc);
+                               return FALSE;
+                       }
+               }
        } while (res == -1);
        
        return res == 1;
@@ -1096,8 +1102,13 @@ ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (MonoObject
        do {
                res = mono_monitor_try_enter_internal (obj, ms, TRUE);
                /*This means we got interrupted during the wait and didn't got the monitor.*/
-               if (res == -1)
-                       mono_thread_interruption_checkpoint ();
+               if (res == -1) {
+                       MonoException *exc = mono_thread_interruption_checkpoint ();
+                       if (exc) {
+                               mono_set_pending_exception (exc);
+                               return;
+                       }
+               }
        } while (res == -1);
        /*It's safe to do it from here since interruption would happen only on the wrapper.*/
        *lockTaken = res == 1;
@@ -1302,8 +1313,7 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
        /* Regain the lock with the previous nest count */
        do {
                regain = mono_monitor_try_enter_inflated (obj, INFINITE, TRUE, id);
-               if (regain == -1) 
-                       mono_thread_interruption_checkpoint ();
+               /* We must regain the lock before handling interruption requests */
        } while (regain == -1);
 
        g_assert (regain == 1);