X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Flttv%2Flttv%2Fmodule.c;h=aab28bca84b0dc71592b4215a1d02428e3a7d939;hb=065f8f4123ad297a3a37864225b73b72cfc2e43a;hp=18cc24e03a2740efd21c10ebca5d8a4e7e431414;hpb=224446ce9bb1b6724122cfdf4e3e716a5526af24;p=lttv.git diff --git a/ltt/branches/poly/lttv/lttv/module.c b/ltt/branches/poly/lttv/lttv/module.c index 18cc24e0..aab28bca 100644 --- a/ltt/branches/poly/lttv/lttv/module.c +++ b/ltt/branches/poly/lttv/lttv/module.c @@ -20,6 +20,10 @@ /* module.c : Implementation of the module loading/unloading mechanism. */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include @@ -70,7 +74,7 @@ static GQuark lttv_module_error; static void init(); -static finish_destroy(); +static void finish_destroy(); static void module_release(LttvModule *m); @@ -129,16 +133,17 @@ static void library_remove(LttvLibrary *l) LttvModule *m; GPtrArray *modules; - + GPtrArray **modules_ptr = &modules; /* for strict aliasing */ guint i; char *key; + char **key_ptr = &key; /* for strict aliasing */ for(i = 0 ; i < l->modules->len ; i++) { m = (LttvModule *)(l->modules->pdata[i]); g_hash_table_lookup_extended(modules_by_name, m->info.name, - (gpointer *)&key, (gpointer *)&modules); + (gpointer *)key_ptr, (gpointer *)modules_ptr); g_assert(modules != NULL); g_ptr_array_remove(modules, m); if(modules->len == 0) { @@ -162,11 +167,12 @@ static void library_remove(LttvLibrary *l) static LttvLibrary *library_load(char *name, GError **error) { - GModule *gm; + GModule *gm = NULL; int i, nb; - char *path, *pathname; + /* path is always initialized, checked */ + char *path = NULL, *pathname; LttvLibrary *l; @@ -189,7 +195,7 @@ static LttvLibrary *library_load(char *name, GError **error) module_chain = NULL; module_next = &module_chain; gm = g_module_open(pathname,0); - g_free(pathname); + g_free(pathname); if(gm != NULL) break; @@ -226,15 +232,15 @@ static LttvLibrary *library_load(char *name, GError **error) LttvLibrary *lttv_library_load(char *name, GError **error) { - LttvLibrary *l = library_load(name, error); - l->info.load_count++; + LttvLibrary *l = library_load(name, error); + if(l != NULL) l->info.load_count++; return l; } - -static void library_unload(LttvLibrary *l) +/* Returns < 0 if still in use, 0 if freed */ +static gint library_unload(LttvLibrary *l) { - guint i, len; + guint i; GModule *gm; @@ -243,13 +249,13 @@ static void library_unload(LttvLibrary *l) if(l->locked_loaded > 0) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: locked loaded", l->info.name); - return; + return 1; } if(l->info.load_count > 0) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "Unload library %s: load count %d", l->info.name, l->info.load_count); - return; + return l->info.load_count; } /* Check if all its modules have been released */ @@ -259,7 +265,7 @@ static void library_unload(LttvLibrary *l) if(m->info.use_count > 0) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO,"Unload library %s: module %s used", l->info.name, m->info.name); - return; + return 1; } } @@ -272,13 +278,21 @@ static void library_unload(LttvLibrary *l) /* insure that module.c will be finalized */ finish_destroy(); + return 0; } -void lttv_library_unload(LttvLibrary *l) +gint lttv_library_unload(LttvLibrary *l) { - l->info.load_count--; - library_unload(l); + /* In the case where we wait for a module to release, the load count is 0 + * and should not be decremented. */ + if(l->info.load_count != 0) { + l->info.load_count--; + return l->info.load_count; + } else { + library_unload(l); + return 0; + } } @@ -288,10 +302,10 @@ static void library_lock_loaded(LttvLibrary *l) } -static void library_unlock_loaded(LttvLibrary *l) +static gint library_unlock_loaded(LttvLibrary *l) { l->locked_loaded--; - library_unload(l); + return library_unload(l); } @@ -520,7 +534,7 @@ static void init() } -static finish_destroy() +static void finish_destroy() { guint i; @@ -555,6 +569,7 @@ static void destroy() locked_libraries = g_new(LttvLibrary *, nb); for(i = 0 ; i < nb ; i++) { + //g_assert(nb == libraries->len); l = (LttvLibrary *)(libraries->pdata[i]); locked_libraries[i] = l; library_lock_loaded(l); @@ -562,7 +577,16 @@ static void destroy() m = (LttvModule *)(l->modules->pdata[j]); while(m->info.require_count > 0) lttv_module_release(m); } - while(l->info.load_count > 0) lttv_library_unload(l); + if(library_unlock_loaded(l) > 0) + while(lttv_library_unload(l) > 0); + + /* If the number of librairies loaded have changed, restart from the + * beginning */ + if(nb != libraries->len) { + i = 0; + nb = libraries->len; + } + } for(i = 0 ; i < nb ; i++) {