Make modules more flexible (builtin or loaded are identical). Add a test module
[lttv.git] / ltt / branches / poly / include / lttv / module.h
index 5d1c3bae708c80af2f08195f84f4efd016f1eff2..e88b7b92afaee406a5f3bd2085cb38331156236a 100644 (file)
+/* This file is part of the Linux Trace Toolkit viewer
+ * Copyright (C) 2003-2004 Michel Dagenais
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 
+ * MA 02111-1307, USA.
+ */
+
 #ifndef MODULES_H
 #define MODULES_H
 
-#include <gmodule.h>
+#include <glib.h>
 
-/* lttv modules are shared object files, to be loaded dynamically, which
-   interact with the main module to provide additional capabilities. They
-   typically register hooks to be called at various places, read and add
-   global or trace attributes, and add menu items and tabbed windows to the
-   graphical user interface. Both the hooks lists and the menus and windows
-   are accessed as global attributes. */
+/* A module contains some functionality which becomes available atfer it is
+   initialized and before it is destroyed. A module is characterized by a name,
+   a description (short and long), a list of names of other modules on which 
+   it depends, and an initialization and a destruction function.
 
+   A library contains one or more modules and may be loaded dynamically.
+   The modules contained in a library are automatically registered through
+   constructors which are called when the library is loaded. For modules
+   directly linked with the main program (builtin), the constructors are
+   called before the main program starts. (However, neither malloc nor glib 
+   functions are used during the registration process).
 
-/* Each lttv module must define a function named "init" with
-   the following signature. The init function may itself load pre-requisite 
-   modules using lttv_module_load. 
+   The library loading path is a set of directories, where requested
+   libraries and modules are searched for.
+*/
 
-   It should also define a function named "destroy", which free the
-   resources reserved during execution.
+typedef struct _LttvModule LttvModule;
 
-   Most modules will not use the command line arguments passed as init 
-   arguments. It is easier to simply register command line options 
-   to be parsed by the main module. However, some modules
-   may require an "early access" to these arguments, for example a embedded
-   python interpreter module which needs to know the modules written in
-   python to load. */
+typedef struct _LttvLibrary LttvLibrary;
 
-/* Initial draft by Michel Dagenais May 2003
- * Reworked by Mathieu Desnoyers, May 2003
- */
+typedef void (*LttvModuleInit)();
 
-/* index_standalone is the index of the module in the modulesStanalone array.
- * If the module is only loaded "DEPENDANT", index is -1.
- */
+typedef void (*LttvModuleDestroy)();
 
-typedef struct lttv_module_info_ {
-  GModule *module;
+typedef struct _LttvModuleInfo
+{
   char *name;
-  char *directory;
-  char *pathname;
-  guint ref_count;
-  gint index_standalone;
-} lttv_module_info;
-
-/* Loading type of modules : 
- * STANDALONE : the program takes care of unloading the moduels
- * DEPENDANT : The module that load this module is required to unload
- *             it in it's destroy function.
- */
+  char *short_description;
+  char *description;
+  LttvModuleInit init;
+  LttvModuleDestroy destroy;
+  LttvLibrary *library;
+  unsigned require_count;
+  unsigned use_count;
+  unsigned prerequisites_number;
+} LttvModuleInfo;
+
+
+typedef struct _LttvLibraryInfo
+{
+  char *name;
+  char *path;
+  unsigned load_count;
+} LttvLibraryInfo;
+
+
+typedef enum _LttvModuleError 
+{
+  LTTV_MODULE_NOT_FOUND,
+  LTTV_MODULE_NO_INIT
+} LttvModuleError;
+
+
+/* Insure that a module is loaded and initialized. Require count 
+   (number of times the module was required) and use count 
+   (number of times required or used as prerequisite) serve to 
+   insure that a module is destroyed only after it has been released 
+   as many times as it was required (and prerequired).
+
+   The module is searched among the modules currently loaded, then as a 
+   similarly named library to load which should contain the named module.
+   If the module cannot be found or loaded, NULL is returned and an
+   explanation is provided in error. */
+
+LttvModule *lttv_module_require(char *name, GError **error);
+
+void lttv_module_release(LttvModule *m);
+
+
+/* Obtain information about the module, including the containing library */
+
+void lttv_module_info(LttvModule *m, LttvModuleInfo *info);
+
+
+/* List the modules on which this module depends */
+
+unsigned lttv_module_prerequisite_number(LttvModule *m);
+
+LttvModule *lttv_module_prerequisite_get(LttvModule *m, unsigned i);
+
+
+/* Insure that a library is loaded. A load count insures that a library 
+   is unloaded only after it has been asked to unload as
+   many times as it was loaded, and its modules are not in use. The library
+   is searched along the library path if name is a relative pathname. 
+   If the library cannot be found or loaded, NULL is returned and an 
+   explanation is provided in error. */
+
+LttvLibrary *lttv_library_load(char *name, GError **error);
 
-typedef enum _loadtype
-{ STANDALONE, DEPENDANT
-} loadtype;
+void lttv_library_unload(LttvLibrary *l);
 
-typedef void (*lttv_module_load_init)(int argc, char **argv) ;
 
+/* Obtain information about the library */
 
-/* Load (if not already loaded) the named module. The init function of the
-   module is executed upon loading. */
+void lttv_library_info(LttvLibrary *l, LttvLibraryInfo *info);
 
-lttv_module_info *lttv_module_load(const char *name, int argc, char **argv,loadtype);
 
+/* List the modules contained in a library */
 
+unsigned lttv_library_module_number(LttvLibrary *l);
 
-/* Unload (if already loaded) the named module. The destroy function of the
-   module is executed before unloading. */
+LttvModule *lttv_library_module_get(LttvLibrary *l, unsigned i);
 
-typedef void (*lttv_module_unload_destroy)() ;
 
-int lttv_module_unload_pathname(const char *pathname,loadtype) ;
+/* List the currently loaded libraries */
 
-int lttv_module_unload_name(const char *name,loadtype) ;
+unsigned lttv_library_number();
 
-int lttv_module_unload(lttv_module_info *moduleInfo,loadtype);
+LttvLibrary *lttv_library_get(unsigned i);
 
-/* Unload all the modules */
-void lttv_module_unload_all();
 
-/* Additional module search paths may be defined. */
 
-void lttv_module_path_add(const char *name);
+/* Add or remove directory names to the library search path */
+
+void lttv_library_path_add(char *name);
+
+void lttv_library_path_remove(char *name);
+
+
+/* List the directory names in the library search path */
+
+unsigned lttv_library_path_number();
+
+char *lttv_library_path_get(unsigned i);
+
+
+/* To define a module, simply call the LTTV_MODULE macro with the needed
+   arguments: single word name, one line short description, larger
+   description, initialization function, destruction function, and
+   list of names for required modules (e.g., "moduleA", "moduleB").
+   This will insure that the module is registered at library load time.
+
+   Example:
+
+   LTTV_MODULE("option", "Command line options processing", "...", \
+       init, destroy, "moduleA", "moduleB") 
+*/
+
+#define LTTV_MODULE(name, short_desc, desc, init, destroy, ...) \
+  \
+  static void _LTTV_MODULE_REGISTER(__LINE__)() \
+      __attribute__((constructor));             \
+  \
+  static void _LTTV_MODULE_REGISTER(__LINE__)() \
+  { \
+    static char *module_prerequisites[] = { __VA_ARGS__ };     \
+    \
+    static struct _LttvModuleDescription module = { \
+        name, short_desc, desc, init, destroy, \
+        sizeof(module_prerequisites) / sizeof(char *), \
+        module_prerequisites, NULL}; \
+        \
+    lttv_module_register(&module); \
+  }
+
+
+/* Internal structure and function used to register modules, called by 
+   LTTV_MODULE */
+
+#define __LTTV_MODULE_REGISTER(line) _lttv_module_register_ ## line
+#define _LTTV_MODULE_REGISTER(line) __LTTV_MODULE_REGISTER(line)
+
+struct _LttvModuleDescription
+{
+  char *name;
+  char *short_description;
+  char *description;
+  LttvModuleInit init;
+  LttvModuleDestroy destroy;
+  unsigned prerequisites_number;
+  char **prerequisites;
+  struct _LttvModuleDescription *next;
+};
+
+void lttv_module_register(struct _LttvModuleDescription *d);
 
 #endif // MODULES_H
+
+
+
+
+
+
This page took 0.030137 seconds and 4 git commands to generate.