[threads] Store MonoInternalThread in MonoThreadInfo for use when detaching (#5058)
authorLudovic Henry <ludovic@xamarin.com>
Tue, 20 Jun 2017 00:35:54 +0000 (20:35 -0400)
committerGitHub <noreply@github.com>
Tue, 20 Jun 2017 00:35:54 +0000 (20:35 -0400)
* [threads] Make mono_thread_attach_full static

* [threads] Remove  prefix on MonoThreadInfoCallbacks callbacks

* [threads] Rename mono_threads*_init functions to mono_thread_info*_init

* [threads] Remove dead method mono_runtime_is_critical_method

* [threads] Move MonoThreadInfoCallbacks to metadata/threads

* [threads] Store MonoInternalThread in MonoThreadInfo for use when detaching

When the native thread would exit, the TLS keys are destroyed. There is a TLS destructor for MonoThreadInfo, but not for MonoInternalThread. If MonoInternalThread is destroyed before MonoThreadInfo, then MonoThreadInfoCallbacks.thread_detach wouldn't successfully detach the current MonoInternalThread as mono_thread_internal_current would return NULL. This would lead to MonoInternalThread still laying around, while their corresponding MonoThreadInfo has already been destroyed. This fixes this problem, since we now rely on MonoThreadInfo to store the MonoInternalThread for detach.

15 files changed:
mono/dis/main.c
mono/metadata/boehm-gc.c
mono/metadata/gc-internals.h
mono/metadata/null-gc.c
mono/metadata/runtime.c
mono/metadata/runtime.h
mono/metadata/sgen-mono.c
mono/metadata/threads-types.h
mono/metadata/threads.c
mono/mini/mini-runtime.c
mono/unit-tests/test-conc-hashtable.c
mono/unit-tests/test-mono-linked-list-set.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h
tools/pedump/pedump.c

index a149edb2608abf6a1e85f517cf465e2c30168ee8..dbbb12a62f8260138aaaa48920358ac80742d0fe 100644 (file)
@@ -2038,7 +2038,7 @@ main (int argc, char *argv [])
 #ifndef HOST_WIN32
        mono_w32handle_init ();
 #endif
-       mono_threads_runtime_init (&ticallbacks);
+       mono_thread_info_runtime_init (&ticallbacks);
 
        mono_install_assembly_load_hook (monodis_assembly_load_hook, NULL);
        mono_install_assembly_search_hook (monodis_assembly_search_hook, NULL);
index 4ad522d4dc3bdb39ef7ed0b8728d76960ddc9618..acbd4eae4b0735bdaef0564e5f2225c780bddddf 100644 (file)
@@ -56,12 +56,6 @@ void *pthread_get_stackaddr_np(pthread_t);
 static gboolean gc_initialized = FALSE;
 static mono_mutex_t mono_gc_lock;
 
-static void*
-boehm_thread_attach (MonoThreadInfo* info);
-static void
-boehm_thread_detach_with_lock (MonoThreadInfo *p);
-static void
-boehm_thread_detach (MonoThreadInfo *p);
 static void
 register_test_toggleref_callback (void);
 
@@ -108,7 +102,6 @@ static void on_gc_heap_resize (size_t new_size);
 void
 mono_gc_base_init (void)
 {
-       MonoThreadInfoCallbacks cb;
        const char *env;
 
        if (gc_initialized)
@@ -237,13 +230,8 @@ mono_gc_base_init (void)
                g_strfreev (opts);
        }
 
-       memset (&cb, 0, sizeof (cb));
-       cb.thread_attach = boehm_thread_attach;
-       cb.thread_detach = boehm_thread_detach;
-       cb.thread_detach_with_lock = boehm_thread_detach_with_lock;
-       cb.mono_method_is_critical = (gboolean (*)(void *))mono_runtime_is_critical_method;
-
-       mono_threads_init (&cb, sizeof (MonoThreadInfo));
+       mono_thread_callbacks_init ();
+       mono_thread_info_init (sizeof (MonoThreadInfo));
        mono_os_mutex_init (&mono_gc_lock);
        mono_os_mutex_init_recursive (&handle_section);
 
@@ -375,8 +363,8 @@ mono_gc_is_gc_thread (void)
        return GC_thread_is_registered ();
 }
 
-static void*
-boehm_thread_attach (MonoThreadInfo* info)
+gpointer
+mono_gc_thread_attach (MonoThreadInfo* info)
 {
        struct GC_stack_base sb;
        int res;
@@ -392,8 +380,8 @@ boehm_thread_attach (MonoThreadInfo* info)
        return info;
 }
 
-static void
-boehm_thread_detach_with_lock (MonoThreadInfo *p)
+void
+mono_gc_thread_detach_with_lock (MonoThreadInfo *p)
 {
        MonoNativeThreadId tid;
 
@@ -405,11 +393,10 @@ boehm_thread_detach_with_lock (MonoThreadInfo *p)
        mono_handle_stack_free (p->handle_stack);
 }
 
-static void
-boehm_thread_detach (MonoThreadInfo *p)
+gboolean
+mono_gc_thread_in_critical_region (MonoThreadInfo *info)
 {
-       if (mono_thread_internal_current_is_attached ())
-               mono_thread_detach_internal (mono_thread_internal_current ());
+       return FALSE;
 }
 
 gboolean
index c6cffb2881b69d78cb4c806b361b1300af28bb94..4473b04d60d9b9d3e02458229c7537fc77be7b03 100644 (file)
@@ -351,6 +351,12 @@ void mono_gc_register_altstack (gpointer stack, gint32 stack_size, gpointer alts
 
 gboolean mono_gc_is_critical_method (MonoMethod *method);
 
+gpointer mono_gc_thread_attach (THREAD_INFO_TYPE *info);
+
+void mono_gc_thread_detach_with_lock (THREAD_INFO_TYPE *info);
+
+gboolean mono_gc_thread_in_critical_region (THREAD_INFO_TYPE *info);
+
 /* If set, print debugging messages around finalizers. */
 extern gboolean log_finalizers;
 
index 9be275916e1736cfaebd789b0a6f03bf383863dd..8d662c0ce5f03f935442e0f0a000075f596ffbe9 100644 (file)
 void
 mono_gc_base_init (void)
 {
-       MonoThreadInfoCallbacks cb;
-
        mono_counters_init ();
 
 #ifndef HOST_WIN32
        mono_w32handle_init ();
 #endif
 
-       memset (&cb, 0, sizeof (cb));
-       /* TODO: This casts away an incompatible pointer type warning in the same
-                manner that boehm-gc does it. This is probably worth investigating
-                more carefully. */
-       cb.mono_method_is_critical = (gpointer)mono_runtime_is_critical_method;
-
-       mono_threads_init (&cb, sizeof (MonoThreadInfo));
+       mono_thread_callbacks_init ();
+       mono_thread_info_init (sizeof (MonoThreadInfo));
 
        mono_thread_info_attach ();
 }
@@ -296,6 +289,23 @@ mono_gc_is_critical_method (MonoMethod *method)
        return FALSE;
 }
 
+gpointer
+mono_gc_thread_attach (MonoThreadInfo* info)
+{
+       return info;
+}
+
+void
+mono_gc_thread_detach_with_lock (MonoThreadInfo *p)
+{
+}
+
+gboolean
+mono_gc_thread_in_critical_region (MonoThreadInfo *info)
+{
+       return FALSE;
+}
+
 int
 mono_gc_get_aligned_size_for_allocator (int size)
 {
index 84fe0d1469e742909ed3a12722d2d4168fa9564a..cd0c0e6123a81ab07a0ee56a2d4aabdf654b25c3 100644 (file)
@@ -114,13 +114,6 @@ mono_runtime_try_shutdown (void)
        return TRUE;
 }
 
-
-gboolean
-mono_runtime_is_critical_method (MonoMethod *method)
-{
-       return FALSE;
-}
-
 /*
 Coordinate the creation of all remaining TLS slots in the runtime.
 No further TLS slots should be created after this function finishes.
index f17f5c9e474cd0b41233360102ecc2ba0d007f47..ddd6d5deb591065e69082ce64edc9f374da69a66 100644 (file)
@@ -18,7 +18,6 @@
 
 MONO_BEGIN_DECLS
 
-gboolean mono_runtime_is_critical_method (MonoMethod *method);
 gboolean mono_runtime_try_shutdown (void);
 
 void mono_runtime_init_tls (void);
index 508a9c68e7a9d286d896eba003c39c4f8ff09c3b..0264158494f283930fde29f68eb244fa42adaf34 100644 (file)
@@ -219,26 +219,6 @@ sgen_has_critical_method (void)
        return sgen_has_managed_allocator ();
 }
 
-static gboolean
-ip_in_critical_region (MonoDomain *domain, gpointer ip)
-{
-       MonoJitInfo *ji;
-       MonoMethod *method;
-
-       /*
-        * We pass false for 'try_aot' so this becomes async safe.
-        * It won't find aot methods whose jit info is not yet loaded,
-        * so we preload their jit info in the JIT.
-        */
-       ji = mono_jit_info_table_find_internal (domain, ip, FALSE, FALSE);
-       if (!ji)
-               return FALSE;
-
-       method = mono_jit_info_get_method (ji);
-
-       return mono_runtime_is_critical_method (method) || sgen_is_critical_method (method);
-}
-
 gboolean
 mono_gc_is_critical_method (MonoMethod *method)
 {
@@ -2208,6 +2188,12 @@ mono_gc_get_gc_callbacks ()
        return &gc_callbacks;
 }
 
+gpointer
+mono_gc_thread_attach (SgenThreadInfo *info)
+{
+       return sgen_thread_attach (info);
+}
+
 void
 sgen_client_thread_attach (SgenThreadInfo* info)
 {
@@ -2234,6 +2220,12 @@ sgen_client_thread_attach (SgenThreadInfo* info)
        info->client_info.info.handle_stack = mono_handle_stack_alloc ();
 }
 
+void
+mono_gc_thread_detach_with_lock (SgenThreadInfo *info)
+{
+       return sgen_thread_detach_with_lock (info);
+}
+
 void
 sgen_client_thread_detach_with_lock (SgenThreadInfo *p)
 {
@@ -2277,25 +2269,12 @@ mono_gc_set_skip_thread (gboolean skip)
        }
 }
 
-static gboolean
-thread_in_critical_region (SgenThreadInfo *info)
+gboolean
+mono_gc_thread_in_critical_region (SgenThreadInfo *info)
 {
        return info->client_info.in_critical_region;
 }
 
-static void
-sgen_thread_detach (SgenThreadInfo *p)
-{
-       /* If a delegate is passed to native code and invoked on a thread we dont
-        * know about, marshal will register it with mono_threads_attach_coop, but
-        * we have no way of knowing when that thread goes away.  SGen has a TSD
-        * so we assume that if the domain is still registered, we can detach
-        * the thread
-        */
-       if (mono_thread_internal_current_is_attached ())
-               mono_thread_detach_internal (mono_thread_internal_current ());
-}
-
 /**
  * mono_gc_is_gc_thread:
  */
@@ -2857,15 +2836,8 @@ sgen_client_vtable_get_name (MonoVTable *vt)
 void
 sgen_client_init (void)
 {
-       MonoThreadInfoCallbacks cb;
-
-       cb.thread_attach = sgen_thread_attach;
-       cb.thread_detach = sgen_thread_detach;
-       cb.thread_detach_with_lock = sgen_thread_detach_with_lock;
-       cb.mono_thread_in_critical_region = thread_in_critical_region;
-       cb.ip_in_critical_region = ip_in_critical_region;
-
-       mono_threads_init (&cb, sizeof (SgenThreadInfo));
+       mono_thread_callbacks_init ();
+       mono_thread_info_init (sizeof (SgenThreadInfo));
 
        ///* Keep this the default for now */
        /* Precise marking is broken on all supported targets. Disable until fixed. */
index 257266e21b6fe5130f3d7e2ac07acbe67bf7d1a2..0a1b6b7d1164b7c9d4c623b07cc36b20d24e734b 100644 (file)
@@ -59,6 +59,9 @@ typedef void (*MonoThreadCleanupFunc) (MonoNativeThreadId tid);
 /* INFO has type MonoThreadInfo* */
 typedef void (*MonoThreadNotifyPendingExcFunc) (gpointer info);
 
+void
+mono_thread_callbacks_init (void);
+
 typedef enum {
        MONO_THREAD_CREATE_FLAGS_NONE         = 0x0,
        MONO_THREAD_CREATE_FLAGS_THREADPOOL   = 0x1,
@@ -237,9 +240,6 @@ void mono_threads_perform_thread_dump (void);
 gboolean
 mono_thread_create_checked (MonoDomain *domain, gpointer func, gpointer arg, MonoError *error);
 
-MonoThread *
-mono_thread_attach_full (MonoDomain *domain, gboolean force_attach);
-
 /* Can't include utils/mono-threads.h because of the THREAD_INFO_TYPE wizardry */
 void mono_threads_add_joinable_thread (gpointer tid);
 void mono_threads_join_threads (void);
index da85ec6e9a0036e32e1f3828e0111b6f0520b78b..69a00d0b6880b51fd2f4a92f6c52973468f77486 100644 (file)
@@ -658,8 +658,18 @@ mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean
        g_assert (thread);
 
        info = mono_thread_info_current ();
+       g_assert (info);
 
        internal = thread->internal_thread;
+       g_assert (internal);
+
+       /* It is needed to store the MonoInternalThread on the MonoThreadInfo, because of the following case:
+        *  - the MonoInternalThread TLS key is destroyed: set it to NULL
+        *  - the MonoThreadInfo TLS key is destroyed: calls mono_thread_info_detach
+        *    - it calls MonoThreadInfoCallbacks.thread_detach
+        *      - mono_thread_internal_current returns NULL -> fails to detach the MonoInternalThread. */
+       mono_thread_info_set_internal_thread_gchandle (info, mono_gchandle_new ((MonoObject*) internal, FALSE));
+
        internal->handle = mono_threads_open_thread_handle (info->handle);
 #ifdef HOST_WIN32
        internal->native_handle = OpenThread (THREAD_ALL_ACCESS, FALSE, GetCurrentThreadId ());
@@ -1077,18 +1087,7 @@ mono_thread_create_checked (MonoDomain *domain, gpointer func, gpointer arg, Mon
        return (NULL != mono_thread_create_internal (domain, func, arg, MONO_THREAD_CREATE_FLAGS_NONE, error));
 }
 
-/**
- * mono_thread_attach:
- */
-MonoThread *
-mono_thread_attach (MonoDomain *domain)
-{
-       MonoThread *thread = mono_thread_attach_full (domain, FALSE);
-
-       return thread;
-}
-
-MonoThread *
+static MonoThread *
 mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
 {
        MonoInternalThread *internal;
@@ -1131,12 +1130,22 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
        return thread;
 }
 
+/**
+ * mono_thread_attach:
+ */
+MonoThread *
+mono_thread_attach (MonoDomain *domain)
+{
+       return mono_thread_attach_full (domain, FALSE);
+}
+
 void
 mono_thread_detach_internal (MonoInternalThread *thread)
 {
        gboolean removed;
 
        g_assert (thread != NULL);
+       SET_CURRENT_OBJECT (thread);
 
        THREAD_DEBUG (g_message ("%s: mono_thread_detach for %p (%"G_GSIZE_FORMAT")", __func__, thread, (gsize)thread->tid));
 
@@ -1265,6 +1274,8 @@ done:
        SET_CURRENT_OBJECT (NULL);
        mono_domain_unset ();
 
+       mono_thread_info_unset_internal_thread_gchandle ((MonoThreadInfo*) thread->thread_info);
+
        /* Don't need to close the handle to this thread, even though we took a
         * reference in mono_thread_attach (), because the GC will do it
         * when the Thread object is finalised.
@@ -2942,6 +2953,84 @@ void mono_thread_init (MonoThreadStartCB start_cb,
        mono_thread_attach_cb = attach_cb;
 }
 
+static gpointer
+thread_attach (MonoThreadInfo *info)
+{
+       return mono_gc_thread_attach (info);
+}
+
+static void
+thread_detach (MonoThreadInfo *info)
+{
+       MonoInternalThread *internal;
+       guint32 gchandle;
+
+       /* If a delegate is passed to native code and invoked on a thread we dont
+        * know about, marshal will register it with mono_threads_attach_coop, but
+        * we have no way of knowing when that thread goes away.  SGen has a TSD
+        * so we assume that if the domain is still registered, we can detach
+        * the thread */
+
+       g_assert (info);
+
+       if (!mono_thread_info_try_get_internal_thread_gchandle (info, &gchandle))
+               return;
+
+       internal = (MonoInternalThread*) mono_gchandle_get_target (gchandle);
+       g_assert (internal);
+
+       mono_gchandle_free (gchandle);
+
+       mono_thread_detach_internal (internal);
+}
+
+static void
+thread_detach_with_lock (MonoThreadInfo *info)
+{
+       return mono_gc_thread_detach_with_lock (info);
+}
+
+static gboolean
+thread_in_critical_region (MonoThreadInfo *info)
+{
+       return mono_gc_thread_in_critical_region (info);
+}
+
+static gboolean
+ip_in_critical_region (MonoDomain *domain, gpointer ip)
+{
+       MonoJitInfo *ji;
+       MonoMethod *method;
+
+       /*
+        * We pass false for 'try_aot' so this becomes async safe.
+        * It won't find aot methods whose jit info is not yet loaded,
+        * so we preload their jit info in the JIT.
+        */
+       ji = mono_jit_info_table_find_internal (domain, ip, FALSE, FALSE);
+       if (!ji)
+               return FALSE;
+
+       method = mono_jit_info_get_method (ji);
+       g_assert (method);
+
+       return mono_gc_is_critical_method (method);
+}
+
+void
+mono_thread_callbacks_init (void)
+{
+       MonoThreadInfoCallbacks cb;
+
+       memset (&cb, 0, sizeof(cb));
+       cb.thread_attach = thread_attach;
+       cb.thread_detach = thread_detach;
+       cb.thread_detach_with_lock = thread_detach_with_lock;
+       cb.ip_in_critical_region = ip_in_critical_region;
+       cb.thread_in_critical_region = thread_in_critical_region;
+       mono_thread_info_callbacks_init (&cb);
+}
+
 /**
  * mono_thread_cleanup:
  */
index 73c880ecf542a950ce8568c3ff2ffbd8a24482dd..ec748153504cadb90ffcddd52c5fac6a2a4cdd16 100644 (file)
@@ -2084,7 +2084,7 @@ lookup_start:
                if ((code = mono_aot_get_method_checked (domain, method, error))) {
                        MonoVTable *vtable;
 
-                       if (mono_runtime_is_critical_method (method) || mono_gc_is_critical_method (method)) {
+                       if (mono_gc_is_critical_method (method)) {
                                /*
                                 * The suspend code needs to be able to lookup these methods by ip in async context,
                                 * so preload their jit info.
@@ -3855,7 +3855,7 @@ mini_init (const char *filename, const char *runtime_version)
        mono_w32handle_init ();
 #endif
 
-       mono_threads_runtime_init (&ticallbacks);
+       mono_thread_info_runtime_init (&ticallbacks);
 
        if (g_hasenv ("MONO_DEBUG")) {
                mini_parse_debug_options ();
@@ -3920,7 +3920,7 @@ mini_init (const char *filename, const char *runtime_version)
        mono_set_generic_sharing_supported (TRUE);
 #endif
 
-       mono_threads_signals_init ();
+       mono_thread_info_signals_init ();
 
 #ifndef MONO_CROSS_COMPILE
        mono_runtime_install_handlers ();
index f01f01b574aa55c9cc9eb69afc51c8ffd0e88b09..b7868f6bda7a7f9f23cc2d00d369821c3a1600e1 100644 (file)
@@ -327,15 +327,14 @@ thread_state_init (MonoThreadUnwindState *ctx)
 int
 main (void)
 {
-       MonoThreadInfoCallbacks cb = { NULL };
        MonoThreadInfoRuntimeCallbacks ticallbacks;
        int res = 0;
 
        CHECKED_MONO_INIT ();
-       mono_threads_init (&cb, sizeof (MonoThreadInfo));
+       mono_thread_info_init (sizeof (MonoThreadInfo));
        memset (&ticallbacks, 0, sizeof (ticallbacks));
        ticallbacks.thread_state_init = thread_state_init;
-       mono_threads_runtime_init (&ticallbacks);
+       mono_thread_info_runtime_init (&ticallbacks);
 #ifndef HOST_WIN32
        mono_w32handle_init ();
 #endif
index a5e01ebe09ec6e5f913e1ad936c822596d39ecde..202d2fc07a11a46caf2006184fb44e72a7d68f84 100644 (file)
@@ -116,15 +116,12 @@ int
 main (int argc, char *argv [])
 {
        int primes [] = { 1, 2, 3, 5, 7, 11, 13, 17 };
-       MonoThreadInfoCallbacks thread_callbacks;
        thread_data_t thread_data [NUM_THREADS];
        int i;
 
-       memset (&thread_callbacks, 0, sizeof (thread_callbacks));
-
        mono_metadata_init ();
 
-       mono_threads_init (&thread_callbacks, 0);
+       mono_thread_info_init (0);
 
        mono_lls_init (&lls, free_node);
 
index 0f85ba1ee1dd845c0ca45e46dbc2e1d968cf43df..a19c9e0be554de1e2e4778962c59e6cc55d3d461 100644 (file)
@@ -380,6 +380,8 @@ register_thread (MonoThreadInfo *info)
 
        info->stackdata = g_byte_array_new ();
 
+       info->internal_thread_gchandle = G_MAXUINT32;
+
        mono_threads_suspend_register (info);
 
        THREADS_DEBUG ("registering info %p tid %p small id %x\n", info, mono_thread_info_get_tid (info), info->small_id);
@@ -610,7 +612,7 @@ mono_thread_info_attach (void)
        {
                /* This can happen from DllMain(DLL_THREAD_ATTACH) on Windows, if a
                 * thread is created before an embedding API user initialized Mono. */
-               THREADS_DEBUG ("mono_thread_info_attach called before mono_threads_init\n");
+               THREADS_DEBUG ("mono_thread_info_attach called before mono_thread_info_init\n");
                return NULL;
        }
 #endif
@@ -640,7 +642,7 @@ mono_thread_info_detach (void)
        {
                /* This can happen from DllMain(THREAD_DETACH) on Windows, if a thread
                 * is created before an embedding API user initialized Mono. */
-               THREADS_DEBUG ("mono_thread_info_detach called before mono_threads_init\n");
+               THREADS_DEBUG ("mono_thread_info_detach called before mono_thread_info_init\n");
                return;
        }
 #endif
@@ -654,6 +656,33 @@ mono_thread_info_detach (void)
        }
 }
 
+gboolean
+mono_thread_info_try_get_internal_thread_gchandle (MonoThreadInfo *info, guint32 *gchandle)
+{
+       g_assert (info);
+
+       if (info->internal_thread_gchandle == G_MAXUINT32)
+               return FALSE;
+
+       *gchandle = info->internal_thread_gchandle;
+       return TRUE;
+}
+
+void
+mono_thread_info_set_internal_thread_gchandle (MonoThreadInfo *info, guint32 gchandle)
+{
+       g_assert (info);
+       g_assert (gchandle != G_MAXUINT32);
+       info->internal_thread_gchandle = gchandle;
+}
+
+void
+mono_thread_info_unset_internal_thread_gchandle (THREAD_INFO_TYPE *info)
+{
+       g_assert (info);
+       info->internal_thread_gchandle = G_MAXUINT32;
+}
+
 /*
  * mono_thread_info_is_exiting:
  *
@@ -685,10 +714,9 @@ thread_info_key_dtor (void *arg)
 #endif
 
 void
-mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size)
+mono_thread_info_init (size_t info_size)
 {
        gboolean res;
-       threads_callbacks = *callbacks;
        thread_info_size = info_size;
        char *sleepLimit;
 #ifdef HOST_WIN32
@@ -737,13 +765,19 @@ mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size)
 }
 
 void
-mono_threads_signals_init (void)
+mono_thread_info_callbacks_init (MonoThreadInfoCallbacks *callbacks)
+{
+       threads_callbacks = *callbacks;
+}
+
+void
+mono_thread_info_signals_init (void)
 {
        mono_threads_suspend_init_signals ();
 }
 
 void
-mono_threads_runtime_init (MonoThreadInfoRuntimeCallbacks *callbacks)
+mono_thread_info_runtime_init (MonoThreadInfoRuntimeCallbacks *callbacks)
 {
        runtime_callbacks = *callbacks;
 }
@@ -841,8 +875,6 @@ WB trampoline. Another option is to encode wb ranges in MonoJitInfo, but that is
 static gboolean
 is_thread_in_critical_region (MonoThreadInfo *info)
 {
-       MonoMethod *method;
-       MonoJitInfo *ji;
        gpointer stack_start;
        MonoThreadUnwindState *state;
 
@@ -854,7 +886,7 @@ is_thread_in_critical_region (MonoThreadInfo *info)
                return TRUE;
 
        /* Are we inside a GC critical region? */
-       if (threads_callbacks.mono_thread_in_critical_region && threads_callbacks.mono_thread_in_critical_region (info)) {
+       if (threads_callbacks.thread_in_critical_region && threads_callbacks.thread_in_critical_region (info)) {
                return TRUE;
        }
 
@@ -871,16 +903,7 @@ is_thread_in_critical_region (MonoThreadInfo *info)
        if (threads_callbacks.ip_in_critical_region)
                return threads_callbacks.ip_in_critical_region ((MonoDomain *) state->unwind_data [MONO_UNWIND_DATA_DOMAIN], (char *) MONO_CONTEXT_GET_IP (&state->ctx));
 
-       ji = mono_jit_info_table_find (
-               (MonoDomain *) state->unwind_data [MONO_UNWIND_DATA_DOMAIN],
-               (char *) MONO_CONTEXT_GET_IP (&state->ctx));
-
-       if (!ji)
-               return FALSE;
-
-       method = mono_jit_info_get_method (ji);
-
-       return threads_callbacks.mono_method_is_critical (method);
+       return FALSE;
 }
 
 gboolean
index 95dd036883447d4a71a15c89ab4e4bc7c4bb54ad..c9686815011f19e814d2283f50c4430994712dc0 100644 (file)
@@ -219,6 +219,9 @@ typedef struct {
 
        /* Stack mark for targets that explicitly require one */
        gpointer stack_mark;
+
+       /* GCHandle to MonoInternalThread */
+       guint32 internal_thread_gchandle;
 } MonoThreadInfo;
 
 typedef struct {
@@ -237,9 +240,8 @@ typedef struct {
        SMR remains functional as its small_id has not been reclaimed.
        */
        void (*thread_detach_with_lock)(THREAD_INFO_TYPE *info);
-       gboolean (*mono_method_is_critical) (void *method);
        gboolean (*ip_in_critical_region) (MonoDomain *domain, gpointer ip);
-       gboolean (*mono_thread_in_critical_region) (THREAD_INFO_TYPE *info);
+       gboolean (*thread_in_critical_region) (THREAD_INFO_TYPE *info);
 } MonoThreadInfoCallbacks;
 
 typedef struct {
@@ -298,13 +300,16 @@ mono_thread_info_set_tid (THREAD_INFO_TYPE *info, MonoNativeThreadId tid)
  * a single block with info from both camps. 
  */
 void
-mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t thread_info_size);
+mono_thread_info_init (size_t thread_info_size);
+
+void
+mono_thread_info_callbacks_init (MonoThreadInfoCallbacks *callbacks);
 
 void
-mono_threads_signals_init (void);
+mono_thread_info_signals_init (void);
 
 void
-mono_threads_runtime_init (MonoThreadInfoRuntimeCallbacks *callbacks);
+mono_thread_info_runtime_init (MonoThreadInfoRuntimeCallbacks *callbacks);
 
 MonoThreadInfoRuntimeCallbacks *
 mono_threads_get_runtime_callbacks (void);
@@ -318,6 +323,15 @@ mono_thread_info_attach (void);
 MONO_API void
 mono_thread_info_detach (void);
 
+gboolean
+mono_thread_info_try_get_internal_thread_gchandle (THREAD_INFO_TYPE *info, guint32 *gchandle);
+
+void
+mono_thread_info_set_internal_thread_gchandle (THREAD_INFO_TYPE *info, guint32 gchandle);
+
+void
+mono_thread_info_unset_internal_thread_gchandle (THREAD_INFO_TYPE *info);
+
 gboolean
 mono_thread_info_is_exiting (void);
 
index 829cda2bdf175fb13137240aa94b0d079346b931..5b76dfd19bd76e10557d59590a0a179bde0add9d 100644 (file)
@@ -671,7 +671,7 @@ main (int argc, char *argv [])
 #ifndef HOST_WIN32
        mono_w32handle_init ();
 #endif
-       mono_threads_runtime_init (&ticallbacks);
+       mono_thread_info_runtime_init (&ticallbacks);
 
        mono_metadata_init ();
        mono_images_init ();