Merge pull request #4434 from BrzVlad/fix-unload-hang
authorVlad Brezae <brezaevlad@gmail.com>
Mon, 27 Feb 2017 20:05:27 +0000 (22:05 +0200)
committerGitHub <noreply@github.com>
Mon, 27 Feb 2017 20:05:27 +0000 (22:05 +0200)
[threads] Don't ignore abort requests in abort protected blocks

1  2 
mono/metadata/threads.c

diff --combined mono/metadata/threads.c
index c756a06c94082952563abe49d4326798d669fb8a,a52c02d2ebf9684cc97fa41760adaa9b571856e5..3461f81e325c6dde6063bb487799a5d24b4baf02
@@@ -695,7 -695,6 +695,7 @@@ mono_thread_attach_internal (MonoThrea
  
        if (shutting_down && !force_attach) {
                mono_threads_unlock ();
 +              mono_thread_pop_appdomain_ref ();
                return FALSE;
        }
  
@@@ -915,7 -914,7 +915,7 @@@ create_thread (MonoThread *thread, Mono
         */
        mono_threads_join_threads ();
  
 -      mono_error_init (error);
 +      error_init (error);
  
        mono_threads_lock ();
        if (shutting_down) {
@@@ -1018,7 -1017,7 +1018,7 @@@ mono_thread_create_internal (MonoDomai
        MonoInternalThread *internal;
        gboolean res;
  
 -      mono_error_init (error);
 +      error_init (error);
  
        internal = create_internal_thread_object ();
  
@@@ -1550,7 -1549,7 +1550,7 @@@ ves_icall_System_Threading_Thread_GetNa
        MonoError error;
        MonoString* str;
  
 -      mono_error_init (&error);
 +      error_init (&error);
  
        LOCK_THREAD (this_obj);
        
@@@ -1572,7 -1571,7 +1572,7 @@@ mono_thread_set_name_internal (MonoInte
  {
        LOCK_THREAD (this_obj);
  
 -      mono_error_init (error);
 +      error_init (error);
  
        if (reset) {
                this_obj->flags &= ~MONO_THREAD_FLAG_NAME_SET;
@@@ -1662,7 -1661,7 +1662,7 @@@ byte_array_to_domain (MonoArray *arr, M
  {
        MonoArray *copy;
  
 -      mono_error_init (error);
 +      error_init (error);
        if (!arr)
                return NULL;
  
@@@ -1743,7 -1742,7 +1743,7 @@@ mono_join_uninterrupted (MonoThreadHand
        gint32 diff_ms;
        gint32 wait = ms;
  
 -      mono_error_init (error);
 +      error_init (error);
  
        start = (ms == -1) ? 0 : mono_msec_ticks ();
        for (;;) {
@@@ -1852,7 -1851,7 +1852,7 @@@ mono_wait_uninterrupted (MonoInternalTh
        gint32 diff_ms;
        gint32 wait = ms;
  
 -      mono_error_init (error);
 +      error_init (error);
  
        start = (ms == -1) ? 0 : mono_100ns_ticks ();
        do {
@@@ -3209,21 -3208,22 +3209,21 @@@ remove_and_abort_threads (gpointer key
        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 +3661,7 @@@ mono_threads_get_thread_dump (MonoArra
        MonoDebugSourceLocation *location;
        int tindex, nthreads;
  
 -      mono_error_init (error);
 +      error_init (error);
        
        *out_threads = NULL;
        *out_stack_frames = NULL;
@@@ -4844,13 -4844,6 +4844,6 @@@ async_abort_critical (MonoThreadInfo *i
        if (mono_get_eh_callbacks ()->mono_install_handler_block_guard (mono_thread_info_get_suspend_state (info)))
                return MonoResumeThread;
  
-       /*
-       The target thread is running at least one protected block, which must not be interrupted, so we give up.
-       The protected block code will give them a chance when appropriate.
-       */
-       if (mono_thread_get_abort_prot_block_count (thread) > 0)
-               return MonoResumeThread;
        /*someone is already interrupting it*/
        if (!mono_thread_set_interruption_requested (thread))
                return MonoResumeThread;
@@@ -4903,7 -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 */