if (!l->public_key_token [0] || !r->public_key_token [0])
return TRUE;
- if (strcmp (l->public_key_token, r->public_key_token))
+ if (strcmp ((char*)l->public_key_token, (char*)r->public_key_token))
return FALSE;
return TRUE;
* The assembly might be under load by this thread. In this case, it is
* safe to return an incomplete instance to prevent loops.
*/
- loading = g_hash_table_lookup (refonly ? assemblies_refonly_loading : assemblies_loading, GetCurrentThread ());
+ loading = g_hash_table_lookup (refonly ? assemblies_refonly_loading : assemblies_loading, GetCurrentThreadId ());
for (tmp = loading; tmp; tmp = tmp->next) {
ass = tmp->data;
if (!mono_assembly_names_equal (aname, &ass->aname))
* a non loaded reference using the ReflectionOnly api
*/
if (!reference)
- reference = (gpointer)-1;
+ reference = REFERENCE_MISSING;
} else
reference = mono_assembly_load (&aname, image->assembly->basedir, &status);
mono_assemblies_lock ();
if (reference == NULL) {
/* Flag as not found */
- reference = (gpointer)-1;
+ reference = REFERENCE_MISSING;
}
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);
+ if (reference != REFERENCE_MISSING){
+ 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);
+ } else {
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Failed to load assembly %s %p\n",
+ image->assembly->aname.name, image->assembly);
+ }
+
image->references [index] = reference;
}
mono_assemblies_unlock ();
assembly_load_hook = hook;
}
+static void
+free_assembly_load_hooks (void)
+{
+ AssemblyLoadHook *hook, *next;
+
+ for (hook = assembly_load_hook; hook; hook = next) {
+ next = hook->next;
+ g_free (hook);
+ }
+}
+
typedef struct AssemblySearchHook AssemblySearchHook;
struct AssemblySearchHook {
AssemblySearchHook *next;
mono_install_assembly_search_hook_internal (func, user_data, FALSE, FALSE);
}
+static void
+free_assembly_search_hooks (void)
+{
+ AssemblySearchHook *hook, *next;
+
+ for (hook = assembly_search_hook; hook; hook = next) {
+ next = hook->next;
+ g_free (hook);
+ }
+}
+
void
mono_install_assembly_refonly_search_hook (MonoAssemblySearchFunc func, gpointer user_data)
{
assembly_refonly_preload_hook = hook;
}
+static void
+free_assembly_preload_hooks (void)
+{
+ AssemblyPreLoadHook *hook, *next;
+
+ for (hook = assembly_preload_hook; hook; hook = next) {
+ next = hook->next;
+ g_free (hook);
+ }
+
+ for (hook = assembly_refonly_preload_hook; hook; hook = next) {
+ next = hook->next;
+ g_free (hook);
+ }
+}
+
static gchar *
absolute_dir (const gchar *filename)
{
return NULL;
}
-static MonoImage*
-do_mono_assembly_open (const char *filename, MonoImageOpenStatus *status, gboolean refonly)
-{
- MonoImage *image = NULL;
-
- if (bundles != NULL){
- image = mono_assembly_open_from_bundle (filename, status, refonly);
-
- if (image != NULL)
- return image;
- }
- mono_assemblies_lock ();
- image = mono_image_open_full (filename, status, refonly);
- mono_assemblies_unlock ();
-
- return image;
-}
-
MonoAssembly *
mono_assembly_open_full (const char *filename, MonoImageOpenStatus *status, gboolean refonly)
{
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY,
"Assembly Loader probing location: '%s'.", filename);
- image = do_mono_assembly_open (fname, status, refonly);
+ image = NULL;
+
+ if (bundles != NULL)
+ image = mono_assembly_open_from_bundle (fname, status, refonly);
+
+ if (!image) {
+ mono_assemblies_lock ();
+ image = mono_image_open_full (fname, status, refonly);
+ mono_assemblies_unlock ();
+ }
if (!image){
- *status = MONO_IMAGE_ERROR_ERRNO;
+ if (*status == MONO_IMAGE_OK)
+ *status = MONO_IMAGE_ERROR_ERRNO;
g_free (fname);
return NULL;
}
if (image->assembly) {
/* Already loaded by another appdomain */
mono_assembly_invoke_load_hook (image->assembly);
+ mono_image_close (image);
+ g_free (fname);
return image->assembly;
}
mono_config_for_assembly (ass->image);
}
+ /* Clear the reference added by mono_image_open */
+ mono_image_close (image);
+
g_free (fname);
return ass;
* mono_assembly_open opens the PE-image pointed by @filename, and
* loads any external assemblies referenced by it.
*
- * NOTE: we could do lazy loading of the assemblies. Or maybe not worth
- * it.
+ * Return: a pointer to the MonoAssembly if @filename contains a valid
+ * assembly or NULL on error. Details about the error are stored in the
+ * @status variable.
*/
MonoAssembly *
mono_assembly_open (const char *filename, MonoImageOpenStatus *status)
MonoAssembly *
mono_assembly_load_from_full (MonoImage *image, const char*fname,
- MonoImageOpenStatus *status, gboolean refonly)
+ MonoImageOpenStatus *status, gboolean refonly)
{
MonoAssembly *ass, *ass2;
char *base_dir;
ass->ref_only = refonly;
ass->image = image;
+ /* Add a non-temporary reference because of ass->image */
mono_image_addref (image);
mono_assembly_fill_assembly_name (image, &ass->aname);
}
}
ass_loading = refonly ? assemblies_refonly_loading : assemblies_loading;
- loading = g_hash_table_lookup (ass_loading, GetCurrentThread ());
+ loading = g_hash_table_lookup (ass_loading, (gpointer)GetCurrentThreadId ());
loading = g_list_prepend (loading, ass);
- g_hash_table_insert (ass_loading, GetCurrentThread (), loading);
+ g_hash_table_insert (ass_loading, (gpointer)GetCurrentThreadId (), loading);
mono_assemblies_unlock ();
g_assert (image->assembly == NULL);
mono_assemblies_lock ();
- loading = g_hash_table_lookup (ass_loading, GetCurrentThread ());
+ loading = g_hash_table_lookup (ass_loading, (gpointer)GetCurrentThreadId ());
loading = g_list_remove (loading, ass);
if (loading == NULL)
/* Prevent memory leaks */
- g_hash_table_remove (ass_loading, GetCurrentThread ());
+ g_hash_table_remove (ass_loading, (gpointer)GetCurrentThreadId ());
else
- g_hash_table_insert (ass_loading, GetCurrentThread (), loading);
+ g_hash_table_insert (ass_loading, (gpointer)GetCurrentThreadId (), loading);
if (*status != MONO_IMAGE_OK) {
mono_assemblies_unlock ();
mono_assembly_close (ass);
* mono_assembly_name_parse:
* @name: name to parse
* @aname: the destination assembly name
-* Returns: true if the name could be parsed.
*
* Parses an assembly qualified type name and assigns the name,
* version, culture and token to the provided assembly name object.
+*
+* Returns: true if the name could be parsed.
*/
gboolean
mono_assembly_name_parse (const char *name, MonoAssemblyName *aname)
return corlib;
}
-
+/**
+ * mono_assembly_load_full:
+ * @aname: A MonoAssemblyName with the assembly name to load.
+ * @basedir: A directory to look up the assembly at.
+ * @status: a pointer to a MonoImageOpenStatus to return the status of the load operation
+ * @refonly: Whether this assembly is being opened in "reflection-only" mode.
+ *
+ * Loads the assembly referenced by @aname, if the value of @basedir is not NULL, it
+ * attempts to load the assembly from that directory before probing the standard locations.
+ *
+ * If the assembly is being opened in reflection-only mode (@refonly set to TRUE) then no
+ * assembly binding takes place.
+ *
+ * Returns: the assembly referenced by @aname loaded or NULL on error. On error the
+ * value pointed by status is updated with an error code.
+ */
MonoAssembly*
mono_assembly_load_full (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus *status, gboolean refonly)
{
return result;
}
+/**
+ * mono_assembly_load:
+ * @aname: A MonoAssemblyName with the assembly name to load.
+ * @basedir: A directory to look up the assembly at.
+ * @status: a pointer to a MonoImageOpenStatus to return the status of the load operation
+ *
+ * Loads the assembly referenced by @aname, if the value of @basedir is not NULL, it
+ * attempts to load the assembly from that directory before probing the standard locations.
+ *
+ * Returns: the assembly referenced by @aname loaded or NULL on error. On error the
+ * value pointed by status is updated with an error code.
+ */
MonoAssembly*
mono_assembly_load (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus *status)
{
return res;
}
+/**
+ * mono_assembly_loaded:
+ * @aname: an assembly to look for.
+ *
+ * Returns: NULL If the given @aname assembly has not been loaded, or a pointer to
+ * a MonoAssembly that matches the MonoAssemblyName specified.
+ */
MonoAssembly*
mono_assembly_loaded (MonoAssemblyName *aname)
{
GSList *tmp;
g_return_if_fail (assembly != NULL);
+ if (assembly == REFERENCE_MISSING)
+ return;
+
/* Might be 0 already */
if (InterlockedDecrement (&assembly->ref_count) > 0)
return;
if (assembly->image->references [i])
mono_assembly_close (assembly->image->references [i]);
}
+
+ g_free (assembly->image->references);
+ assembly->image->references = NULL;
}
assembly->image->assembly = NULL;
}
g_slist_free (assembly->friend_assembly_names);
g_free (assembly->basedir);
- if (!assembly->dynamic)
+ if (assembly->dynamic) {
+ g_free ((char*)assembly->aname.culture);
+ } else {
g_free (assembly);
+ }
}
MonoImage*
g_list_free (copy);
}
+/**
+ * mono_assemblies_cleanup:
+ *
+ * Free all resources used by this module.
+ */
+void
+mono_assemblies_cleanup (void)
+{
+ GSList *l;
+
+ DeleteCriticalSection (&assemblies_mutex);
+
+ g_hash_table_destroy (assemblies_loading);
+ g_hash_table_destroy (assemblies_refonly_loading);
+
+ for (l = loaded_assembly_bindings; l; l = l->next) {
+ MonoAssemblyBindingInfo *info = l->data;
+
+ mono_assembly_binding_info_free (info);
+ g_free (info);
+ }
+ g_slist_free (loaded_assembly_bindings);
+
+ free_assembly_load_hooks ();
+ free_assembly_search_hooks ();
+ free_assembly_preload_hooks ();
+}
+
/*
* Holds the assembly of the application, for
* System.Diagnostics.Process::MainModule
void
mono_assembly_set_main (MonoAssembly *assembly)
{
- main_assembly=assembly;
+ main_assembly = assembly;
}
+/**
+ * mono_assembly_get_main:
+ *
+ * Returns: the assembly for the application, the first assembly that is loaded by the VM
+ */
MonoAssembly *
mono_assembly_get_main (void)
{
- return(main_assembly);
+ return (main_assembly);
}
-/*
+/**
+ * mono_assembly_get_image:
+ * @assembly: The assembly to retrieve the image from
+ *
+ * Returns: the MonoImage associated with this assembly.
*/
MonoImage*
mono_assembly_get_image (MonoAssembly *assembly)