/*
* mono_threads_attach_coop: called by native->managed wrappers
*
- * In non-coop mode:
- * - @dummy: is NULL
+ * - @dummy:
+ * - blocking mode: contains gc unsafe transition cookie
+ * - non-blocking mode: contains random data
* - @return: the original domain which needs to be restored, or NULL.
- *
- * In coop mode:
- * - @dummy: contains the original domain
- * - @return: a cookie containing current MonoThreadInfo*.
*/
gpointer
mono_threads_attach_coop (MonoDomain *domain, gpointer *dummy)
{
MonoDomain *orig;
- gboolean fresh_thread = FALSE;
+ MonoThreadInfo *info;
+ gboolean external;
+
+ orig = mono_domain_get ();
if (!domain) {
/* Happens when called from AOTed code which is only used in the root domain. */
domain = mono_get_root_domain ();
+ g_assert (domain);
}
- g_assert (domain);
-
/* On coop, when we detached, we moved the thread from RUNNING->BLOCKING.
* If we try to reattach we do a BLOCKING->RUNNING transition. If the thread
* is fresh, mono_thread_attach() will do a STARTING->RUNNING transition so
* we're only responsible for making the cookie. */
- if (mono_threads_is_coop_enabled ()) {
- MonoThreadInfo *info = mono_thread_info_current_unchecked ();
- fresh_thread = !info || !mono_thread_info_is_live (info);
- }
+ if (mono_threads_is_blocking_transition_enabled ())
+ external = !(info = mono_thread_info_current_unchecked ()) || !mono_thread_info_is_live (info);
if (!mono_thread_internal_current ()) {
mono_thread_attach_full (domain, FALSE);
mono_thread_set_state (mono_thread_internal_current (), ThreadState_Background);
}
- orig = mono_domain_get ();
if (orig != domain)
mono_domain_set (domain, TRUE);
- if (!mono_threads_is_coop_enabled ())
- return orig != domain ? orig : NULL;
-
- if (fresh_thread) {
- *dummy = NULL;
- /* mono_thread_attach put the thread in RUNNING mode from STARTING, but we need to
- * return the right cookie. */
- return mono_threads_enter_gc_unsafe_region_cookie ();
- } else {
- *dummy = orig;
- /* thread state (BLOCKING|RUNNING) -> RUNNING */
- return mono_threads_enter_gc_unsafe_region (dummy);
+ if (mono_threads_is_blocking_transition_enabled ()) {
+ if (external) {
+ /* mono_thread_attach put the thread in RUNNING mode from STARTING, but we need to
+ * return the right cookie. */
+ *dummy = mono_threads_enter_gc_unsafe_region_cookie ();
+ } else {
+ /* thread state (BLOCKING|RUNNING) -> RUNNING */
+ *dummy = mono_threads_enter_gc_unsafe_region (dummy);
+ }
}
+
+ return orig;
}
/*
* mono_threads_detach_coop: called by native->managed wrappers
*
- * In non-coop mode:
* - @cookie: the original domain which needs to be restored, or NULL.
- * - @dummy: is NULL
- *
- * In coop mode:
- * - @cookie: contains current MonoThreadInfo* if it was in BLOCKING mode, NULL otherwise
- * - @dummy: contains the original domain
+ * - @dummy:
+ * - blocking mode: contains gc unsafe transition cookie
+ * - non-blocking mode: contains random data
*/
void
mono_threads_detach_coop (gpointer cookie, gpointer *dummy)
{
MonoDomain *domain, *orig;
- if (!mono_threads_is_coop_enabled ()) {
- orig = (MonoDomain*) cookie;
- if (orig)
- mono_domain_set (orig, TRUE);
- } else {
- orig = (MonoDomain*) *dummy;
+ orig = (MonoDomain*) cookie;
- domain = mono_domain_get ();
- g_assert (domain);
+ domain = mono_domain_get ();
+ g_assert (domain);
+ if (mono_threads_is_blocking_transition_enabled ()) {
/* it won't do anything if cookie is NULL
* thread state RUNNING -> (RUNNING|BLOCKING) */
- mono_threads_exit_gc_unsafe_region (cookie, dummy);
+ mono_threads_exit_gc_unsafe_region (*dummy, dummy);
+ }
- if (orig != domain) {
- if (!orig)
- mono_domain_unset ();
- else
- mono_domain_set (orig, TRUE);
- }
+ if (orig != domain) {
+ if (!orig)
+ mono_domain_unset ();
+ else
+ mono_domain_set (orig, TRUE);
}
}