@@ -2433,35 +2433,46 @@ mono_aot_init (void)
2433
2433
/*
2434
2434
* load_container_amodule:
2435
2435
*
2436
- * Load the container assembly and its AOT image.
2436
+ * Load AOT module of a container assembly
2437
2437
*/
2438
2438
static void
2439
2439
load_container_amodule (MonoAssemblyLoadContext * alc )
2440
2440
{
2441
- ERROR_DECL (error );
2442
-
2441
+ // If container_amodule loaded, don't lock the runtime
2443
2442
if (!container_assm_name || container_amodule )
2444
2443
return ;
2445
2444
2446
- char * local_ref = container_assm_name ;
2447
- container_assm_name = NULL ;
2448
- MonoImageOpenStatus status = MONO_IMAGE_OK ;
2449
- MonoAssemblyOpenRequest req ;
2450
- gchar * dll = g_strdup_printf ( "%s.dll" , local_ref );
2451
- /*
2452
- * Don't fire managed assembly load events whose execution
2453
- * might require this module to be already loaded.
2454
- */
2455
- mono_assembly_request_prepare_open (& req , alc );
2456
- req .request .no_managed_load_event = TRUE;
2457
- MonoAssembly * assm = mono_assembly_request_open (dll , & req , & status );
2458
- if (!assm ) {
2459
- gchar * exe = g_strdup_printf ("%s.exe" , local_ref );
2460
- assm = mono_assembly_request_open (exe , & req , & status );
2461
- }
2462
- g_assert (assm );
2463
- load_aot_module (alc , assm , NULL , error );
2464
- container_amodule = assm -> image -> aot_module ;
2445
+ mono_loader_lock ();
2446
+ // There might be several threads that passed the first check
2447
+ // Adding another check to ensure single load of a container assembly due to race condition
2448
+ if (!container_amodule ) {
2449
+ ERROR_DECL (error );
2450
+
2451
+ // This method is recursively invoked within the same thread during AOT module loads
2452
+ // It avoids recursive invocation by setting container_assm_name to NULL
2453
+ char * local_ref = container_assm_name ;
2454
+ container_assm_name = NULL ;
2455
+
2456
+ // Create a fake MonoAssembly/MonoImage to retrieve its AOT module.
2457
+ // Container MonoAssembly/MonoImage shouldn't be used during the runtime.
2458
+ MonoAssembly * assm = g_new0 (MonoAssembly , 1 );
2459
+ assm -> image = g_new0 (MonoImage , 1 );
2460
+ assm -> image -> dynamic = 0 ;
2461
+ assm -> image -> alc = alc ;
2462
+ assm -> aname .name = local_ref ;
2463
+
2464
+ mono_image_init (assm -> image );
2465
+ MonoAotFileInfo * info = (MonoAotFileInfo * )g_hash_table_lookup (static_aot_modules , assm -> aname .name );
2466
+ assm -> image -> guid = (char * )info -> assembly_guid ;
2467
+ mono_assembly_addref (assm );
2468
+
2469
+ load_aot_module (alc , assm , NULL , error );
2470
+ mono_memory_barrier ();
2471
+ g_assert (assm -> image -> aot_module );
2472
+ container_amodule = assm -> image -> aot_module ;
2473
+ }
2474
+
2475
+ mono_loader_unlock ();
2465
2476
}
2466
2477
2467
2478
static gboolean
0 commit comments