Merge pull request #2816 from xmcclure/profile-clean-0
[mono.git] / mono / metadata / threads.c
index 3c04b893353af7833b67fbbb70cc52f2f6a1c9aa..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>
@@ -1583,7 +1584,7 @@ mono_wait_uninterrupted (MonoInternalThread *thread, gboolean multiple, guint32
 }
 
 /* FIXME: exitContext isnt documented */
-gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext)
+gint32 ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext)
 {
        HANDLE *handles;
        guint32 numhandles;
@@ -1616,15 +1617,7 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_
 
        g_free(handles);
 
-       if(ret==WAIT_FAILED) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       } else if(ret==WAIT_TIMEOUT) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       }
-       
-       return(TRUE);
+       return ret;
 }
 
 /* FIXME: exitContext isnt documented */
@@ -1676,7 +1669,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
 }
 
 /* FIXME: exitContext isnt documented */
-gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this_obj, HANDLE handle, gint32 ms, gboolean exitContext)
+gint32 ves_icall_System_Threading_WaitHandle_WaitOne_internal(HANDLE handle, gint32 ms, gboolean exitContext)
 {
        guint32 ret;
        MonoInternalThread *thread = mono_thread_internal_current ();
@@ -1695,18 +1688,10 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this
        
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
        
-       if(ret==WAIT_FAILED) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       } else if(ret==WAIT_TIMEOUT) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       }
-       
-       return(TRUE);
+       return ret;
 }
 
-gboolean
+gint32
 ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, HANDLE toWait, gint32 ms, gboolean exitContext)
 {
        guint32 ret;
@@ -1725,7 +1710,7 @@ ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, H
        
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 
-       return  (!(ret == WAIT_TIMEOUT || ret == WAIT_IO_COMPLETION || ret == WAIT_FAILED));
+       return ret;
 }
 
 HANDLE ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created)
@@ -2045,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;
@@ -4687,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;
 }