Hide some more methods
[mono.git] / mono / metadata / assembly.c
index b32914c7d08c0b53365360121dab6da32ae3d86a..b72ce7fb3fc38e3fc62f93269442ca7d5b258595 100644 (file)
@@ -878,12 +878,13 @@ mono_assembly_load_reference (MonoImage *image, int index)
        if (reference == NULL) {
                /* Flag as not found */
                reference = (gpointer)-1;
-       } else {
-               mono_assembly_addref (reference);
        }       
 
-       if (!image->references [index])
+       if (!image->references [index]) {
+               mono_assembly_addref (reference);
+               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly Ref addref %s %p -> %s %p: %d\n", image->assembly->aname.name, image->assembly, reference->aname.name, reference, reference->ref_count);
                image->references [index] = reference;
+       }
        mono_assemblies_unlock ();
 
        if (image->references [index] != reference) {
@@ -1249,6 +1250,12 @@ mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboo
                return NULL;
        }
 
+       if (image->assembly) {
+               /* Already loaded by another appdomain */
+               mono_assembly_invoke_load_hook (image->assembly);
+               return image->assembly;
+       }
+
        ass = mono_assembly_load_from_full (image, fname, status, refonly);
 
        if (ass) {
@@ -1363,10 +1370,13 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname,
        ass->basedir = base_dir;
        ass->ref_only = refonly;
        ass->image = image;
-       ass->ref_count = 1;
+
+       mono_image_addref (image);
 
        mono_assembly_fill_assembly_name (image, &ass->aname);
 
+       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Image addref %s %p -> %s %p: %d\n", ass->aname.name, ass, image->name, image, image->ref_count);
+
        /* 
         * Atomically search the loaded list and add ourselves to it if necessary.
         */
@@ -1389,6 +1399,7 @@ mono_assembly_load_from_full (MonoImage *image, const char*fname,
        g_hash_table_insert (ass_loading, GetCurrentThread (), loading);
        mono_assemblies_unlock ();
 
+       g_assert (image->assembly == NULL);
        image->assembly = ass;
 
        mono_assembly_load_references (image, status);
@@ -2172,15 +2183,26 @@ mono_assembly_close (MonoAssembly *assembly)
        GSList *tmp;
        g_return_if_fail (assembly != NULL);
 
-       if (InterlockedDecrement (&assembly->ref_count))
+       /* Might be 0 already */
+       if (InterlockedDecrement (&assembly->ref_count) > 0)
                return;
-       
+
+       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Unloading assembly %s [%p].", assembly->aname.name, assembly);
+
        mono_assemblies_lock ();
        loaded_assemblies = g_list_remove (loaded_assemblies, assembly);
        mono_assemblies_unlock ();
-       /* assemblies belong to domains, so the domain code takes care of unloading the
-        * referenced assemblies
-        */
+
+       if (assembly->image->references) {
+               int i;
+
+               for (i = 0; assembly->image->references [i]; i++) {
+                       if (assembly->image->references [i])
+                               mono_assembly_close (assembly->image->references [i]);
+               }
+       }
+
+       assembly->image->assembly = NULL;
 
        mono_image_close (assembly->image);