premilinary add of modular user interface implementation with a few test modules.
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Thu, 29 May 2003 13:14:59 +0000 (13:14 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Thu, 29 May 2003 13:14:59 +0000 (13:14 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@13 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/lttv/hook.c [new file with mode: 0644]
ltt/branches/poly/lttv/main.c [new file with mode: 0644]
ltt/branches/poly/lttv/module.c [new file with mode: 0644]
ltt/branches/poly/lttv/option.c [new file with mode: 0644]
ltt/branches/poly/lttv/test/sampledep.c [new file with mode: 0644]
ltt/branches/poly/lttv/test/samplemodule.c [new file with mode: 0644]
ltt/branches/poly/lttv/test/samplemodule2.c [new file with mode: 0644]

diff --git a/ltt/branches/poly/lttv/hook.c b/ltt/branches/poly/lttv/hook.c
new file mode 100644 (file)
index 0000000..18ed98e
--- /dev/null
@@ -0,0 +1,76 @@
+#include <lttv/hook.h>
+
+
+typedef struct _lttv_hook_closure {
+  lttv_hook hook;
+  void *hook_data;
+} lttv_hook_closure;
+
+
+inline lttv_hooks *lttv_hooks_new() {
+  return g_array_new(FALSE, FALSE, sizeof(lttv_hook_closure));
+}
+
+/* MD: delete elements of the array also, but don't free pointed addresses
+ * (functions).
+ */
+inline void lttv_hooks_destroy(lttv_hooks *h) {
+  g_array_free(h, TRUE);
+}
+
+inline void lttv_hooks_add(lttv_hooks *h, lttv_hook f, void *hook_data) {
+  lttv_hook_closure c;
+
+  /* if h is null, do nothing, or popup a warning message */
+  if(h == NULL)return;
+
+  c.hook = f;
+  c.hook_data = hook_data;
+  g_array_append_val(h,c);
+}
+
+
+void lttv_hooks_call(lttv_hooks *h, void *call_data)
+{
+  int i;
+  lttv_hook_closure * c;
+
+  for(i = 0 ; i < h->len ; i++) {
+    c = ((lttv_hook_closure *)h->data) + i;
+    if(c != NULL)
+           c->hook(c->hook_data,call_data);
+    else
+           g_critical("NULL hook called\n");
+  }
+}
+
+
+/* Sometimes different hooks need to be called based on the case. The
+   case is represented by an unsigned integer id and may represent different
+   event types, for instance. */
+
+inline lttv_hooks_by_id *lttv_hooks_by_id_new() {
+  return g_ptr_array_new();
+}
+
+
+inline void lttv_hooks_by_id_destroy(lttv_hooks_by_id *h) {
+  /* MD: delete elements of the array also */
+  g_ptr_array_free(h, TRUE);
+}
+
+
+void lttv_hooks_by_id_add(lttv_hooks_by_id *h, lttv_hook f, void *hook_data, 
+    unsigned int id)
+{
+  if(h->len < id) g_ptr_array_set_size(h, id);
+  if(h->pdata[id] == NULL) h->pdata[id] = lttv_hooks_new();
+  lttv_hooks_add(h->pdata[id], f, hook_data);
+}
+
+void lttv_hooks_by_id_call(lttv_hooks_by_id *h, void *call_data, unsigned int id)
+{
+  if(h->len <= id || h->pdata[id] == NULL) return;
+  lttv_hooks_call(h->pdata[id],call_data);
+}
+
diff --git a/ltt/branches/poly/lttv/main.c b/ltt/branches/poly/lttv/main.c
new file mode 100644 (file)
index 0000000..fdb44c7
--- /dev/null
@@ -0,0 +1,144 @@
+
+#include <lttv/lttv.h>
+#include <lttv/trace.h>
+
+
+/* The main program maintains a few central data structures and relies
+   on modules for the rest. These data structures may be accessed by modules
+   through an exported API */
+
+/* Extensible array of popt command line options. Modules add options as
+   they are loaded and initialized. */
+
+
+lttv_attributes *attributes_global;
+
+static lttv_hooks
+  *hooks_init_after,
+  *hooks_program_before,
+  *hooks_program_main,
+  *hooks_program_after;
+
+// trace sets has to be put one in each new window_traceset
+static lttv_trace_set *traces;
+
+static char *aModule, *aPath, *aTrace;
+
+static int aArgc;
+
+static char **aArgv;
+
+static void lttv_module_option(void *hook_data);
+
+static void lttv_module_path_option(void *hook_data);
+
+static void lttv_trace_option(void *hook_data);
+
+#ifdef MEMDEBUG
+extern struct GMemVTable *glib_mem_profiler_table;
+#endif
+
+/* Since everything is done in modules, the main program only takes care
+   of the infrastructure. */
+
+int main(int argc, char **argv) {
+
+  aArgc = argc;
+  aArgv = argv;
+
+#ifdef MEMDEBUG
+  g_mem_set_vtable(glib_mem_profiler_table);
+  g_message("Memory summary before main");
+  g_mem_profile();
+#endif
+
+  attributes_global = lttv_attributes_new();
+
+//  traces = lttv_trace_set_new();
+//  lttv_attributes_set_pointer_pathname(attributes_global, "trace_set/default", traces);
+
+  /* Initialize the hooks */
+
+  hooks_init_after = lttv_hooks_new();
+  lttv_attributes_set_pointer_pathname(attributes_global, "hooks/init/after", 
+      hooks_init_after);
+
+
+  hooks_program_before = lttv_hooks_new();
+  lttv_attributes_set_pointer_pathname(attributes_global, "hooks/program/before", 
+      hooks_program_before);
+
+  hooks_program_main = lttv_hooks_new();
+  lttv_attributes_set_pointer_pathname(attributes_global, "hooks/program/main", 
+      hooks_program_main);
+
+  hooks_program_after = lttv_hooks_new();
+  lttv_attributes_set_pointer_pathname(attributes_global, "hooks/program/after", 
+      hooks_program_after);
+
+  /* Initialize the command line options processing */
+
+  lttv_option_init(argc,argv);
+  lttv_module_init(argc,argv);
+  // FIXME lttv_analyse_init(argc,argv);
+
+  /* Initialize the module loading */
+
+  lttv_module_path_add("/usr/lib/lttv/plugins");
+
+  /* Add some built-in options */
+
+  lttv_option_add("module",'m', "load a module", "name of module to load", 
+      LTTV_OPT_STRING, &aModule, lttv_module_option, NULL);
+  lttv_option_add("modules-path", 'L', 
+      "add a directory to the module search path", 
+      "directory to add to the path", LTTV_OPT_STRING, &aPath, 
+      lttv_module_path_option, NULL);
+
+  lttv_option_add("trace", 't', 
+      "add a trace to the trace set to analyse", 
+      "pathname of the directory containing the trace", 
+      LTTV_OPT_STRING, &aTrace, lttv_trace_option, NULL);
+
+  lttv_hooks_call(hooks_init_after, NULL);
+
+  lttv_hooks_call(hooks_program_before, NULL);
+  lttv_hooks_call(hooks_program_main, NULL);
+  lttv_hooks_call(hooks_program_after, NULL);
+
+  /* Finalize the command line options processing */
+  lttv_module_destroy();
+  lttv_option_destroy();
+  // FIXME lttv_analyse_destroy();
+  lttv_attributes_destroy(attributes_global);
+
+#ifdef MEMDEBUG
+    g_message("Memory summary after main");
+    g_mem_profile();
+#endif
+
+  
+}
+
+void lttv_module_option(void *hook_data)
+{ 
+  lttv_module_load(aModule,aArgc,aArgv,STANDALONE);
+}
+
+
+void lttv_module_path_option(void *hook_data)
+{
+  lttv_module_path_add(aPath);
+}
+
+
+void lttv_trace_option(void *hook_data)
+{ 
+//  lttv_trace *trace;
+
+//  trace = lttv_trace_open(aTrace);
+//  if(trace == NULL) g_critical("cannot open trace %s", aTrace);
+//  lttv_trace_set_add(traces, trace);
+}
+
diff --git a/ltt/branches/poly/lttv/module.c b/ltt/branches/poly/lttv/module.c
new file mode 100644 (file)
index 0000000..ae71950
--- /dev/null
@@ -0,0 +1,290 @@
+
+/* module.c : Implementation of the module loading/unloading mechanism.
+ * 
+ */
+
+/* Initial draft by Michel Dagenais May 2003
+ * Reworked by Mathieu Desnoyers, May 2003
+ */
+
+#include <lttv/lttv.h>
+#include <lttv/module.h>
+#include <popt.h>
+
+/* Table of loaded modules and paths where to search for modules */
+
+static GHashTable *modules = NULL;
+
+static GPtrArray *modulesStandalone = NULL;
+
+static GPtrArray *modulesPaths = NULL;
+
+void lttv_module_init(int argc, char **argv) {
+  modules = g_hash_table_new(g_str_hash, g_str_equal);
+  modulesStandalone = g_ptr_array_new();
+  modulesPaths = g_ptr_array_new();
+}
+
+void lttv_module_destroy() {
+  
+  int i;
+
+  /* Unload all modules */
+  lttv_module_unload_all();
+
+  /* Free the modules paths pointer array as well as the elements */
+  for(i = 0; i< modulesPaths->len; i++) {
+    g_free(modulesPaths->pdata[i]);
+  }
+  g_ptr_array_free(modulesPaths,TRUE) ;
+  g_ptr_array_free(modulesStandalone,TRUE) ;
+  modulesPaths = NULL;
+  modulesStandalone = NULL;
+  
+  /* destroy the hash table */
+  g_hash_table_destroy(modules) ;
+  modules = NULL;
+}
+
+/* Add a new pathname to the modules loading search path */
+
+void lttv_module_path_add(const char *name) {
+  g_ptr_array_add(modulesPaths,(char*)g_strdup(name));
+}
+
+
+/* Load (if not already loaded) the named module. Its init function is
+   called. We pass the options of the command line to it in case it has
+   preliminary things to get from it. Note that the normal way to add a
+   command line option for a module is through the options parsing mecanism.
+   */
+
+lttv_module_info *lttv_module_load(const char *name, int argc, char **argv, loadtype load) {
+
+  GModule *gmodule;
+
+  lttv_module_info *moduleInfo;
+
+  int i;
+
+  char *pathname;
+  
+  lttv_module_load_init init_Function;
+
+  /* Find and load the module, It will increase the usage counter
+   * If the module is already loaded, only the reference counter will
+   * be incremented. It's part of the gmodule architecture. Very useful
+   * for modules dependencies.
+   */
+
+  g_assert(name != NULL);
+
+  for(i = 0 ; i < modulesPaths->len ; i++) {
+    pathname = g_module_build_path(modulesPaths->pdata[i],name);
+    gmodule = g_module_open(pathname,0) ;
+    
+    
+    if(gmodule != NULL) {
+      g_message("Loading module %s ... found!",pathname);
+
+      /* Was the module already opened? */
+      moduleInfo = g_hash_table_lookup(modules,g_module_name(gmodule));
+
+      /* First time the module is opened */
+
+      if(moduleInfo == NULL ) {
+        moduleInfo = g_new(lttv_module_info, 1);
+        moduleInfo->module = gmodule;
+        moduleInfo->pathname = g_module_name(gmodule);
+        moduleInfo->directory = modulesPaths->pdata[i];
+        moduleInfo->name = (char *)g_strdup(name);
+       moduleInfo->ref_count = 0;
+       moduleInfo->index_standalone = -1;
+        g_hash_table_insert(modules, moduleInfo->pathname, moduleInfo);
+        if(!g_module_symbol(gmodule, "init", (gpointer) &init_Function)) {
+         g_critical("module %s (%s) does not have init function",
+            moduleInfo->pathname,moduleInfo->name);
+       }
+        else {
+          init_Function(argc,argv);
+        }
+      }
+
+      /* Add the module in the standalone array if the module is
+       * standalone and not in the array. Otherwise, set index to
+       * -1 (dependant only).
+       */
+      if(load == STANDALONE) {
+             
+        if(moduleInfo->index_standalone == -1) {
+               
+          g_ptr_array_add(modulesStandalone, moduleInfo);
+          moduleInfo->index_standalone = modulesStandalone->len - 1;
+
+         moduleInfo->ref_count++ ;  
+        }
+       else {
+          g_warning("Module %s is already loaded standalone.",pathname);
+         /* Decrease the gmodule use_count. Has previously been increased in the g_module_open. */
+         g_module_close(moduleInfo->module) ;
+       }
+      }
+      else { /* DEPENDANT */
+         moduleInfo->ref_count++ ;
+      }
+
+      return moduleInfo;
+    }
+    g_message("Loading module %s ... missing.",pathname);
+    g_free(pathname);
+  }
+  g_critical("module %s not found",name);
+  return NULL;
+}
+
+/* Unload the named module. */
+
+int lttv_module_unload_pathname(const char *pathname, loadtype load) {
+
+  lttv_module_info *moduleInfo;
+
+  moduleInfo = g_hash_table_lookup(modules, pathname);
+
+  /* If no module of that name is loaded, nothing to unload. */
+  if(moduleInfo != NULL) {
+    g_message("Unloading module %s : is loaded.\n", pathname) ;
+    lttv_module_unload(moduleInfo, load) ;
+    return 1;
+  }
+  else {
+    g_message("Unloading module %s : is not loaded.\n", pathname) ;
+    return 0;
+  }
+}
+
+int lttv_module_unload_name(const char *name, loadtype load) {
+
+  int i;
+
+  char *pathname;
+  
+  /* Find and load the module, It will increase the usage counter
+   * If the module is already loaded, only the reference counter will
+   * be incremented. It's part of the gmodule architecture. Very useful
+   * for modules dependencies.
+   */
+
+  g_assert(name != NULL);
+
+  for(i = 0 ; i < modulesPaths->len ; i++) {
+
+    pathname = g_module_build_path(modulesPaths->pdata[i],name);
+    
+    if(lttv_module_unload_pathname(pathname, load) == TRUE)
+      return TRUE ;
+  }
+  g_critical("module %s not found",name);
+  return FALSE;
+}
+
+
+
+/* Unload the module. We use a call_gclose boolean to keep the g_module_close call
+ * after the call to the module's destroy function. */
+  
+int lttv_module_unload(lttv_module_info *moduleInfo, loadtype load) {
+
+  lttv_module_unload_destroy destroy_Function;
+
+  char *moduleName ;
+
+  gboolean call_gclose = FALSE;
+
+  if(moduleInfo == NULL) return FALSE;
+
+ /* Closing the module decrements the usage counter if previously higher than
+  * 1. If 1, it unloads the module.
+  */
+
+  /* Add the module in the standalone array if the module is
+   * standalone and not in the array. Otherwise, set index to
+   * -1 (dependant only).
+   */
+  if(load == STANDALONE) {
+     
+    if(moduleInfo->index_standalone == -1) {
+       
+      g_warning("Module %s is not loaded standalone.",moduleInfo->pathname);
+    }
+    else {
+      /* We do not remove the element of the array, it would change
+       * the index orders. We will have to check if index is -1 in
+       * unload all modules.
+       */
+      moduleInfo->index_standalone = -1;
+      g_message("Unloading module %s, reference count passes from %u to %u",
+           moduleInfo->pathname,moduleInfo->ref_count,
+           moduleInfo->ref_count-1);
+
+      moduleInfo->ref_count-- ;
+      call_gclose = TRUE ;
+    }
+  }
+  else { /* DEPENDANT */
+    g_message("Unloading module %s, reference count passes from %u to %u",
+              moduleInfo->pathname,
+              moduleInfo->ref_count,moduleInfo->ref_count-1);
+
+              moduleInfo->ref_count-- ;
+             call_gclose = TRUE ;
+  }
+
+  /* The module is really closing if ref_count is 0 */
+  if(!moduleInfo->ref_count) {
+    g_message("Unloading module %s : closing module.",moduleInfo->pathname);
+
+    /* Call the destroy function of the module */
+    if(!g_module_symbol(moduleInfo->module, "destroy", (gpointer) &destroy_Function)) {
+       g_critical("module %s (%s) does not have destroy function",
+                       moduleInfo->pathname,moduleInfo->name);
+    }
+    else {
+       destroy_Function();
+    }
+  
+    /* If the module will effectively be closed, remove the moduleInfo from
+     * the hash table and free the module name.
+     */
+    g_free(moduleInfo->name) ;
+
+    g_hash_table_remove(modules, moduleInfo->pathname);
+  }
+  
+  if(call_gclose) g_module_close(moduleInfo->module) ;
+
+  return TRUE ;
+}
+
+#define MODULE_I ((lttv_module_info *)modulesStandalone->pdata[i])
+
+/* unload all the modules in the hash table, calling module_destroy for
+ * each of them.
+ *
+ * We first take all the moduleInfo in the hash table, put it in an
+ * array. We use qsort on the array to have the use count of 1 first.
+ */
+void lttv_module_unload_all() {
+       
+  int i = 0;
+
+  /* call the unload for each module.
+   */
+  for(i = 0; i < modulesStandalone->len; i++) {
+         
+    if(MODULE_I->index_standalone != -1) {
+    lttv_module_unload(MODULE_I,STANDALONE) ;
+    }
+  }
+}
diff --git a/ltt/branches/poly/lttv/option.c b/ltt/branches/poly/lttv/option.c
new file mode 100644 (file)
index 0000000..aa8656f
--- /dev/null
@@ -0,0 +1,180 @@
+
+#include <lttv/lttv.h>
+#include <popt.h>
+
+/* Extensible array of popt command line options. Modules add options as
+   they are loaded and initialized. */
+
+typedef struct _lttv_option {
+  lttv_option_hook hook;
+  void *hook_data;
+} lttv_option;
+
+extern lttv_attributes *attributes_global;
+
+static GArray *lttv_options_command;
+
+static GArray *lttv_options_command_popt;
+
+// unneeded   static lttv_key *key ;
+
+static int command_argc;
+
+static char **command_argv;
+
+/* Lists of hooks to be called at different places */
+
+static lttv_hooks
+  *hooks_options_before,
+  *hooks_options_after;
+
+static gboolean init_done = FALSE;
+
+void lttv_options_command_parse(void *hook_data, void *call_data);
+
+
+void lttv_option_init(int argc, char **argv) {
+
+  lttv_hooks *hooks_init_after;
+
+  if(init_done) return;
+  else init_done = TRUE;
+
+  command_argc = argc;
+  command_argv = argv;
+
+  hooks_options_before = lttv_hooks_new();
+  hooks_options_after = lttv_hooks_new();
+
+  lttv_attributes_set_pointer_pathname(attributes_global, 
+      "hooks/options/before", hooks_options_before);
+
+  lttv_attributes_set_pointer_pathname(attributes_global,
+      "hooks/options/after",  hooks_options_after);
+
+  lttv_options_command_popt = g_array_new(0,0,sizeof(struct poptOption));
+  lttv_options_command = g_array_new(0,0,sizeof(lttv_option));
+
+  hooks_init_after = lttv_attributes_get_pointer_pathname(attributes_global,
+                 "hooks/init/after");
+  lttv_hooks_add(hooks_init_after, lttv_options_command_parse, NULL);
+
+}
+
+void lttv_option_destroy() {
+
+  g_array_free(lttv_options_command_popt,TRUE) ;
+  g_array_free(lttv_options_command,TRUE) ;
+
+  lttv_attributes_set_pointer_pathname(attributes_global, 
+      "hooks/options/before", NULL);
+
+  lttv_attributes_set_pointer_pathname(attributes_global,
+      "hooks/options/after",  NULL);
+
+  lttv_hooks_destroy(hooks_options_before);
+  lttv_hooks_destroy(hooks_options_after);
+
+}
+
+
+static int poptToLTT[] = { 
+  POPT_ARG_NONE, POPT_ARG_STRING, POPT_ARG_INT, POPT_ARG_LONG
+};
+
+
+void lttv_option_add(char *long_name, char char_name, char *description, 
+    char *argDescription, lttv_option_type t, void *p, 
+    lttv_option_hook h, void *hook_data)
+{
+  struct poptOption poption;
+
+  lttv_option option;
+
+  poption.longName = long_name;
+  poption.shortName = char_name;
+  poption.descrip = description;
+  poption.argDescrip = argDescription;
+  poption.argInfo = poptToLTT[t];
+  poption.arg = p;
+  poption.val = lttv_options_command->len + 1;
+
+  option.hook = h;
+  option.hook_data = hook_data;
+
+  g_array_append_val(lttv_options_command_popt,poption);
+  g_array_append_val(lttv_options_command,option);
+}
+
+
+static struct poptOption endOption = { NULL, '\0', 0, NULL, 0};
+
+/* As we may load modules in the hooks called for argument processing,
+ * we have to recreate the argument context each time the
+ * lttv_options_command_popt is modified. This way we will be able to
+ * parse arguments defined by the modules
+ */
+
+void lttv_options_command_parse(void *hook_data, void *call_data) 
+{
+  int rc;
+  int lastrc;
+  poptContext c;
+  lttv_option *option;
+
+  lttv_hooks_call(hooks_options_before,NULL);
+  /* Always add then remove the null option around the get context */
+  g_array_append_val(lttv_options_command_popt, endOption);
+  /* Compiler warning caused by const char ** for command_argv in header */
+  /* Nothing we can do about it. Header should not put it const. */
+  c = poptGetContext("lttv", command_argc, (const char**)command_argv,
+      (struct poptOption *)(lttv_options_command_popt->data),0);
+
+  /* We remove the null option here to be able to add options correctly */
+  g_array_remove_index(lttv_options_command_popt,
+                 lttv_options_command_popt->len - 1);
+
+  /* There is no last good offset */
+  lastrc = -1;
+
+  /* Parse options while not end of options event */
+  while((rc = poptGetNextOpt(c)) != -1) {
+         
+    if(rc == POPT_ERROR_BADOPT) {
+      /* We need to redo the context with information added by modules */
+      g_array_append_val(lttv_options_command_popt, endOption);
+      poptFreeContext(c);  
+      c = poptGetContext("lttv", command_argc, (const char**)command_argv,
+          (struct poptOption *)lttv_options_command_popt->data,0);
+      g_array_remove_index(lttv_options_command_popt,
+                 lttv_options_command_popt->len);
+
+      /* Cut out the already parsed elements */
+      if(lastrc != -1)
+        while(poptGetNextOpt(c) != lastrc) { } ;
+      
+      /* Get the same option once again */
+      g_assert(rc = poptGetNextOpt(c) != -1) ;
+      if(rc == POPT_ERROR_BADOPT) {
+        /* If here again we have a parsing error with all context info ok,
+        * then there is a problem in the arguments themself, give up */
+        g_critical("option %s: %s", poptBadOption(c,0), poptStrerror(rc));
+       break ;
+      }
+    }
+    
+    /* Remember this offset as the last good option value */
+    lastrc = rc;
+
+    /* Execute the hook registered with this option */
+    option = ((lttv_option *)lttv_options_command->data) + rc - 1;
+    if(option->hook != NULL) option->hook(option->hook_data);
+  }
+
+  poptFreeContext(c);
+
+  lttv_hooks_call(hooks_options_after,NULL);
+  
+}
+
diff --git a/ltt/branches/poly/lttv/test/sampledep.c b/ltt/branches/poly/lttv/test/sampledep.c
new file mode 100644 (file)
index 0000000..8275982
--- /dev/null
@@ -0,0 +1,21 @@
+/* Sample module for Linux Trace Toolkit new generation User Interface */
+
+/* Created by Mathieu Desnoyers, may 2003 */
+
+#include <glib.h>
+#include <gmodule.h>
+
+/* Include module.h from lttv headers for module loading */
+#include "../../include/lttv/module.h"
+
+G_MODULE_EXPORT void init() {
+       g_critical("Sample module dependant init()");
+
+       lttv_module_load("samplemodule",0,NULL,DEPENDANT);
+}
+
+G_MODULE_EXPORT void destroy() {
+       g_critical("Sample module dependant destroy()");
+       lttv_module_unload_name("samplemodule",DEPENDANT);
+}
+       
diff --git a/ltt/branches/poly/lttv/test/samplemodule.c b/ltt/branches/poly/lttv/test/samplemodule.c
new file mode 100644 (file)
index 0000000..53240aa
--- /dev/null
@@ -0,0 +1,19 @@
+/* Sample module for Linux Trace Toolkit new generation User Interface */
+
+/* Created by Mathieu Desnoyers, may 2003 */
+
+#include <glib.h>
+#include <gmodule.h>
+
+#include "../../include/lttv/attribute.h"
+
+extern lttv_attributes *attributes_global;
+
+G_MODULE_EXPORT void init() {
+       g_critical("Sample module init()");
+}
+
+G_MODULE_EXPORT void destroy() {
+       g_critical("Sample module destroy()");
+}
+       
diff --git a/ltt/branches/poly/lttv/test/samplemodule2.c b/ltt/branches/poly/lttv/test/samplemodule2.c
new file mode 100644 (file)
index 0000000..03fbfe4
--- /dev/null
@@ -0,0 +1,19 @@
+/* Sample module for Linux Trace Toolkit new generation User Interface */
+
+/* Created by Mathieu Desnoyers, may 2003 */
+
+#include <glib.h>
+#include <gmodule.h>
+
+#include "../../include/lttv/attribute.h"
+
+extern lttv_attributes *attributes_global;
+
+G_MODULE_EXPORT void init() {
+       g_critical("Sample module 2 init()");
+}
+
+G_MODULE_EXPORT void destroy() {
+       g_critical("Sample module 2 destroy()");
+}
+       
This page took 0.031803 seconds and 4 git commands to generate.