Merge pull request #4434 from BrzVlad/fix-unload-hang
[mono.git] / mono / metadata / threads.c
index a52c02d2ebf9684cc97fa41760adaa9b571856e5..3461f81e325c6dde6063bb487799a5d24b4baf02 100644 (file)
@@ -695,6 +695,7 @@ mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean
 
        if (shutting_down && !force_attach) {
                mono_threads_unlock ();
+               mono_thread_pop_appdomain_ref ();
                return FALSE;
        }
 
@@ -914,7 +915,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
         */
        mono_threads_join_threads ();
 
-       mono_error_init (error);
+       error_init (error);
 
        mono_threads_lock ();
        if (shutting_down) {
@@ -1017,7 +1018,7 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
        MonoInternalThread *internal;
        gboolean res;
 
-       mono_error_init (error);
+       error_init (error);
 
        internal = create_internal_thread_object ();
 
@@ -1549,7 +1550,7 @@ ves_icall_System_Threading_Thread_GetName_internal (MonoInternalThread *this_obj
        MonoError error;
        MonoString* str;
 
-       mono_error_init (&error);
+       error_init (&error);
 
        LOCK_THREAD (this_obj);
        
@@ -1571,7 +1572,7 @@ mono_thread_set_name_internal (MonoInternalThread *this_obj, MonoString *name, g
 {
        LOCK_THREAD (this_obj);
 
-       mono_error_init (error);
+       error_init (error);
 
        if (reset) {
                this_obj->flags &= ~MONO_THREAD_FLAG_NAME_SET;
@@ -1661,7 +1662,7 @@ byte_array_to_domain (MonoArray *arr, MonoDomain *domain, MonoError *error)
 {
        MonoArray *copy;
 
-       mono_error_init (error);
+       error_init (error);
        if (!arr)
                return NULL;
 
@@ -1742,7 +1743,7 @@ mono_join_uninterrupted (MonoThreadHandle* thread_to_join, gint32 ms, MonoError
        gint32 diff_ms;
        gint32 wait = ms;
 
-       mono_error_init (error);
+       error_init (error);
 
        start = (ms == -1) ? 0 : mono_msec_ticks ();
        for (;;) {
@@ -1851,7 +1852,7 @@ mono_wait_uninterrupted (MonoInternalThread *thread, guint32 numhandles, gpointe
        gint32 diff_ms;
        gint32 wait = ms;
 
-       mono_error_init (error);
+       error_init (error);
 
        start = (ms == -1) ? 0 : mono_100ns_ticks ();
        do {
@@ -3208,22 +3209,21 @@ remove_and_abort_threads (gpointer key, gpointer value, gpointer user)
        if (wait->num >= MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS)
                return FALSE;
 
-       /* The finalizer thread is not a background thread */
-       if (!mono_native_thread_id_equals (thread_get_tid (thread), self)
-            && (thread->state & ThreadState_Background) != 0
-            && (thread->flags & MONO_THREAD_FLAG_DONT_MANAGE) == 0
-       ) {
+       if (mono_native_thread_id_equals (thread_get_tid (thread), self))
+               return FALSE;
+       if (mono_gc_is_finalizer_internal_thread (thread))
+               return FALSE;
+
+       if ((thread->state & ThreadState_Background) && !(thread->flags & MONO_THREAD_FLAG_DONT_MANAGE)) {
                wait->handles[wait->num] = mono_threads_open_thread_handle (thread->handle);
                wait->threads[wait->num] = thread;
                wait->num++;
 
                THREAD_DEBUG (g_print ("%s: Aborting id: %"G_GSIZE_FORMAT"\n", __func__, (gsize)thread->tid));
                mono_thread_internal_abort (thread);
-               return TRUE;
        }
 
-       return !mono_native_thread_id_equals (thread_get_tid (thread), self)
-               && !mono_gc_is_finalizer_internal_thread (thread);
+       return TRUE;
 }
 
 /** 
@@ -3661,7 +3661,7 @@ mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_fra
        MonoDebugSourceLocation *location;
        int tindex, nthreads;
 
-       mono_error_init (error);
+       error_init (error);
        
        *out_threads = NULL;
        *out_stack_frames = NULL;
@@ -4896,7 +4896,7 @@ self_abort_internal (MonoError *error)
 {
        MonoException *exc;
 
-       mono_error_init (error);
+       error_init (error);
 
        /* FIXME this is insanely broken, it doesn't cause interruption to happen synchronously
         * since passing FALSE to mono_thread_request_interruption makes sure it returns NULL */