#include <mono/metadata/environment.h>
#include "mono/metadata/profiler-private.h"
#include "mono/metadata/security-manager.h"
-#include "mono/metadata/mono-debug-debugger.h"
#include <mono/metadata/verify-internals.h>
#include <mono/metadata/reflection-internals.h>
#include <mono/metadata/w32event.h>
MonoNativeThreadId tid;
int do_initialization = 0;
MonoDomain *last_domain = NULL;
- MonoException * pending_tae = NULL;
+ gboolean pending_tae = FALSE;
error_init (error);
return TRUE;
}
/* see if the thread doing the initialization is already blocked on this thread */
+ gboolean is_blocked = TRUE;
blocked = GUINT_TO_POINTER (MONO_NATIVE_THREAD_ID_TO_UINT (lock->initializing_tid));
while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) {
if (mono_native_thread_id_equals (pending_lock->initializing_tid, tid)) {
/* the thread doing the initialization is blocked on this thread,
but on a lock that has already been freed. It just hasn't got
time to awake */
+ is_blocked = FALSE;
break;
}
}
}
++lock->waiting_count;
/* record the fact that we are waiting on the initializing thread */
- g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
+ if (is_blocked)
+ g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
}
mono_type_initialization_unlock ();
mono_threads_begin_abort_protected_block ();
mono_runtime_try_invoke (method, NULL, NULL, (MonoObject**) &exc, error);
- gboolean got_pending_interrupt = mono_threads_end_abort_protected_block ();
+ mono_threads_end_abort_protected_block ();
//exception extracted, error will be set to the right value later
if (exc == NULL && !mono_error_ok (error))//invoking failed but exc was not set
mono_coop_cond_broadcast (&lock->cond);
mono_type_init_unlock (lock);
- //This can happen if the cctor self-aborts
- if (exc && mono_object_class (exc) == mono_defaults.threadabortexception_class)
- pending_tae = exc;
-
- //TAEs are blocked around .cctors, they must escape as soon as no cctor is left to run.
- if (!pending_tae && got_pending_interrupt)
- pending_tae = mono_thread_try_resume_interruption ();
+ /*
+ * This can happen if the cctor self-aborts. We need to reactivate tae
+ * (next interruption checkpoint will throw it) and make sure we won't
+ * throw tie for the type.
+ */
+ if (exc && mono_object_class (exc) == mono_defaults.threadabortexception_class) {
+ pending_tae = TRUE;
+ mono_thread_resume_interruption (FALSE);
+ }
} else {
/* this just blocks until the initializing thread is done */
mono_type_init_lock (lock);
vtable->initialized = 1;
mono_type_initialization_unlock ();
- //TAE wins over TIE
- if (pending_tae)
- mono_error_set_exception_instance (error, pending_tae);
- else if (vtable->init_failed) {
+ /* If vtable init fails because of TAE, we don't throw TIE, only the TAE */
+ if (vtable->init_failed && !pending_tae) {
/* Either we were the initializing thread or we waited for the initialization */
mono_error_set_exception_instance (error, get_type_init_exception_for_vtable (vtable));
return FALSE;