Make modules more flexible (builtin or loaded are identical). Add a test module
[lttv.git] / ltt / branches / poly / include / lttv / module.h
index 39319151f8184bc5fbd0ddc745d96ade65a8db46..e88b7b92afaee406a5f3bd2085cb38331156236a 100644 (file)
 #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
-   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.
 
-   Each lttv module must define a function named "init" with
-   the following signature. The init function may itself require other
-   modules using lttv_module_require. 
+   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).
 
-   It should also define a function named "destroy" to free the
-   resources reserved during execution.
-
-   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 an embedded
-   python interpreter module which needs to know the modules written in
-   python to load. */
+   The library loading path is a set of directories, where requested
+   libraries and modules are searched for.
+*/
 
 typedef struct _LttvModule LttvModule;
 
-typedef void (*LttvModuleInit)(LttvModule *self, int argc, char **argv);
+typedef struct _LttvLibrary LttvLibrary;
+
+typedef void (*LttvModuleInit)();
 
 typedef void (*LttvModuleDestroy)();
 
+typedef struct _LttvModuleInfo
+{
+  char *name;
+  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);
 
-/* Additional module search paths may be defined. */
+void lttv_library_unload(LttvLibrary *l);
 
-void lttv_module_path_add(const char *name);
 
+/* Obtain information about the library */
 
-/* Load (or increment its reference count if already loaded) the named module.
-   The init function of the module is executed upon loading. */
+void lttv_library_info(LttvLibrary *l, LttvLibraryInfo *info);
 
-LttvModule *lttv_module_load(const char *name, int argc, char **argv);
 
+/* List the modules contained in a library */
 
-/* Module m depends on the named module. The named module will be loaded,
-   remembered by m as a dependent, and unloaded when m is unloaded. */
+unsigned lttv_library_module_number(LttvLibrary *l);
 
-LttvModule *lttv_module_require(LttvModule *m, const char *name, int argc,
-    char **argv);
+LttvModule *lttv_library_module_get(LttvLibrary *l, unsigned i);
 
 
-/* Decrement the reference count of the specified module and unload it if 0.
-   The destroy function of the module is executed before unloading. 
-   Dependent modules are unloaded. */
+/* List the currently loaded libraries */
 
-void lttv_module_unload(LttvModule *m) ;
+unsigned lttv_library_number();
 
+LttvLibrary *lttv_library_get(unsigned i);
 
-/* List the loaded modules. The returned array contains nb elements and
-   must be freed with g_free. */
 
-LttvModule **lttv_module_list(guint *nb);
 
+/* Add or remove directory names to the library search path */
 
-/* Obtain information about a module. The list of dependent module is
-   returned and must be freed with g_free. */
+void lttv_library_path_add(char *name);
 
-LttvModule **lttv_module_info(LttvModule *m, const char **name, 
-    guint *ref_count, guint *load_count, guint *nb_dependents);
+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);
 
-char * lttv_module_name(LttvModule *m);
 #endif // MODULES_H
+
+
+
+
+
+
This page took 0.026877 seconds and 4 git commands to generate.