Merge pull request #2810 from kumpera/fix_hazard_free
[mono.git] / mono / metadata / threads.c
index 1cb5e238b4d94a10ed676668d4bd1f308122aa79..5884d0270e58ee9ce7dd577fc37d3d16a8a4fced 100644 (file)
@@ -9,6 +9,7 @@
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <config.h>
@@ -2029,6 +2030,7 @@ MonoObject*
 ves_icall_System_Threading_Interlocked_Exchange_T (MonoObject **location, MonoObject *value)
 {
        MonoObject *res;
+       MONO_CHECK_NULL (location, NULL);
        res = (MonoObject *)InterlockedExchangePointer ((volatile gpointer *)location, value);
        mono_gc_wbarrier_generic_nostore (location);
        return res;
@@ -4671,7 +4673,17 @@ mono_thread_info_get_last_managed (MonoThreadInfo *info)
        MonoJitInfo *ji = NULL;
        if (!info)
                return NULL;
+
+       /*
+        * The suspended thread might be holding runtime locks. Make sure we don't try taking
+        * any runtime locks while unwinding. In coop case we shouldn't safepoint in regions
+        * where we hold runtime locks.
+        */
+       if (!mono_threads_is_coop_enabled ())
+               mono_thread_info_set_is_async_context (TRUE);
        mono_get_eh_callbacks ()->mono_walk_stack_with_state (last_managed, mono_thread_info_get_suspend_state (info), MONO_UNWIND_SIGNAL_SAFE, &ji);
+       if (!mono_threads_is_coop_enabled ())
+               mono_thread_info_set_is_async_context (FALSE);
        return ji;
 }