@@ -86,6 +86,12 @@ gboolean mono_dont_free_domains;
8686#define mono_appdomains_unlock () mono_coop_mutex_unlock (&appdomains_mutex)
8787static MonoCoopMutex appdomains_mutex ;
8888
89+ /* Lock used to prevent domain enumeration while domains may be unloading.
90+ * This lock must be taken before any other domain-related locks to prevent deadlock.
91+ * See https://github.com/Unity-Technologies/mono/pull/2173
92+ */
93+ MonoCoopMutex mono_domain_unload_mutex ;
94+
8995static MonoDomain * mono_root_domain = NULL ;
9096
9197/* some statistics */
@@ -559,6 +565,7 @@ mono_init_internal (const char *filename, const char *exe_filename, const char *
559565 mono_thread_info_attach ();
560566
561567 mono_coop_mutex_init_recursive (& appdomains_mutex );
568+ mono_coop_mutex_init_recursive (& mono_domain_unload_mutex );
562569
563570 mono_metadata_init ();
564571 mono_images_init ();
@@ -925,6 +932,7 @@ mono_cleanup (void)
925932 mono_metadata_cleanup ();
926933
927934 mono_coop_mutex_destroy (& appdomains_mutex );
935+ mono_coop_mutex_destroy (& mono_domain_unload_mutex );
928936
929937 mono_w32process_cleanup ();
930938 mono_w32file_cleanup ();
@@ -1041,6 +1049,14 @@ mono_domain_foreach (MonoDomainFunc func, gpointer user_data)
10411049 MONO_EXIT_GC_UNSAFE ;
10421050}
10431051
1052+ void
1053+ mono_unity_domain_foreach_locked (MonoDomainFunc func , gpointer user_data )
1054+ {
1055+ mono_coop_mutex_lock (& mono_domain_unload_mutex );
1056+ mono_domain_foreach (func , user_data );
1057+ mono_coop_mutex_unlock (& mono_domain_unload_mutex );
1058+ }
1059+
10441060void
10451061mono_domain_ensure_entry_assembly (MonoDomain * domain , MonoAssembly * assembly )
10461062{
0 commit comments