usertrace update for powerpc
[lttv.git] / ltt / branches / poly / lttv / lttv / module.c
index 18cc24e03a2740efd21c10ebca5d8a4e7e431414..aab28bca84b0dc71592b4215a1d02428e3a7d939 100644 (file)
 
 /* module.c : Implementation of the module loading/unloading mechanism. */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <lttv/module.h>
 #include <gmodule.h>
 
@@ -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++) {
This page took 0.026781 seconds and 4 git commands to generate.