diff --git a/src/backend/interfaceregistry.c b/src/backend/interfaceregistry.c index ffa979340..cc175dd0a 100644 --- a/src/backend/interfaceregistry.c +++ b/src/backend/interfaceregistry.c @@ -53,13 +53,15 @@ key_fn (const PSplaynode node); static LumieraInterfacenode -lumiera_interfacenode_new (LumieraInterface iface) +lumiera_interfacenode_new (LumieraInterface iface, LumieraPlugin plugin) { LumieraInterfacenode self = lumiera_malloc (sizeof (*self)); psplaynode_init (&self->node); self->interface = iface; self->refcnt = 0; + self->plugin = plugin; + FIXME ("plugin handling (refcnt, atime)"); self->lnk = NULL; self->deps_size = 0; self->deps = NULL; @@ -74,6 +76,7 @@ lumiera_interfacenode_delete (LumieraInterfacenode self) if (self) { REQUIRE (self->refcnt == 0); + FIXME ("plugin handling"); lumiera_free (self->deps); lumiera_free (self); } @@ -115,7 +118,7 @@ lumiera_interfaceregistry_destroy (void) void -lumiera_interfaceregistry_register_interface (LumieraInterface self) +lumiera_interfaceregistry_register_interface (LumieraInterface self, LumieraPlugin plugin) { TRACE (interfaceregistry); REQUIRE (self); @@ -123,13 +126,13 @@ lumiera_interfaceregistry_register_interface (LumieraInterface self) LUMIERA_RECMUTEX_SECTION (interfaceregistry, &lumiera_interface_mutex) { TRACE (interfaceregistry, "interface %s, version %d, instance %s", self->interface, self->version, self->name); - psplay_insert (lumiera_interfaceregistry, &lumiera_interfacenode_new (self)->node, 100); + psplay_insert (lumiera_interfaceregistry, &lumiera_interfacenode_new (self, plugin)->node, 100); } } void -lumiera_interfaceregistry_bulkregister_interfaces (LumieraInterface* self) +lumiera_interfaceregistry_bulkregister_interfaces (LumieraInterface* self, LumieraPlugin plugin) { TRACE (interfaceregistry); REQUIRE (self); @@ -139,7 +142,7 @@ lumiera_interfaceregistry_bulkregister_interfaces (LumieraInterface* self) while (*self) { TRACE (interfaceregistry, "interface %s, version %d, instance %s", (*self)->interface, (*self)->version, (*self)->name); - psplay_insert (lumiera_interfaceregistry, &lumiera_interfacenode_new (*self)->node, 100); + psplay_insert (lumiera_interfaceregistry, &lumiera_interfacenode_new (*self, plugin)->node, 100); ++self; } } diff --git a/src/backend/interfaceregistry.h b/src/backend/interfaceregistry.h index 02481072d..54ede293a 100644 --- a/src/backend/interfaceregistry.h +++ b/src/backend/interfaceregistry.h @@ -25,6 +25,7 @@ #include "lib/psplay.h" #include "backend/interface.h" +#include "backend/plugin.h" #include @@ -62,6 +63,10 @@ struct lumiera_interfacenode_struct /** reference counters and link used for internal reference management */ unsigned refcnt; + + /** backreference to its plugin if it comes from a plugin, else NULL */ + LumieraPlugin plugin; + /** temporary used to stack interfaces when recursively opening/closing them */ LumieraInterfacenode lnk; /** allocated size of the following deps table */ @@ -84,10 +89,10 @@ lumiera_interfaceregistry_destroy (void); void -lumiera_interfaceregistry_register_interface (LumieraInterface self); +lumiera_interfaceregistry_register_interface (LumieraInterface self, LumieraPlugin plugin); void -lumiera_interfaceregistry_bulkregister_interfaces (LumieraInterface* self); +lumiera_interfaceregistry_bulkregister_interfaces (LumieraInterface* self, LumieraPlugin plugin); void lumiera_interfaceregistry_remove_interface (LumieraInterface self); diff --git a/src/backend/plugin.h b/src/backend/plugin.h index 7e17afc18..6696e395f 100644 --- a/src/backend/plugin.h +++ b/src/backend/plugin.h @@ -21,111 +21,68 @@ #ifndef LUMIERA_PLUGIN_H #define LUMIERA_PLUGIN_H -#ifdef __cplusplus -extern "C" { -#elif 0 -} /*eek, fixes emacs indenting for now*/ -#endif #include #include -#include "error.h" +#include "lib/error.h" /** * @file - * Plugin loader, header. + * Lumiera plugins defines 'interfaces' as shown in interface.h, the plugin system handles the loading + * of all kinds of plugins under the hood, invoked from the interface system. Anything defined here is + * called internally and should not be used by other parts of the application. */ -NOBUG_DECLARE_FLAG (lumiera_plugin); +LUMIERA_ERROR_DECLARE(PLUGIN_DLOPEN); + + +NOBUG_DECLARE_FLAG (plugin); /* tool macros*/ -#define LUMIERA_INTERFACE_TYPE(name, version) struct lumiera_interface_##name##_##version -#define LUMIERA_INTERFACE_CAST(name, version) (LUMIERA_INTERFACE_TYPE(name, version)*) - -/* Interface definition */ -#define LUMIERA_INTERFACE(name, version, ...) \ -LUMIERA_INTERFACE_TYPE(name, version) \ -{ \ - struct lumiera_interface interface_header_; \ - __VA_ARGS__ \ -} - -#define LUMIERA_INTERFACE_PROTO(ret, name, params) ret (*name) params; - -/* Interface instantiation */ -#define LUMIERA_INTERFACE_IMPLEMENT(iname, version, name, open, close, ...) \ -LUMIERA_INTERFACE_TYPE(iname, version) name##_##version = \ -{ \ - { \ - version, \ - sizeof(LUMIERA_INTERFACE_TYPE(iname, version)), \ - NULL, \ - 0, \ - open, \ - close \ - }, \ - __VA_ARGS__ \ -} +struct lumiera_plugin_struct; +typedef struct lumiera_plugin_struct lumiera_plugin; +typedef lumiera_plugin* LumieraPlugin; -/* internally used */ -struct lumiera_plugin; - -/** - * This is the header for any interface exported by plugins. - * Real interfaces append their functions at the end. There are few standard functions on each Interface - * Every function is required to be implemnted. - */ -struct lumiera_interface -{ - /// interface version number - unsigned version; - /// size of the full structure is used to determine the revision (adding a new function increments the size) - size_t size; - /// back reference to plugin - struct lumiera_plugin* plugin; - /// incremented for each user of this interface and decremented when closed - unsigned use_count; - - /// called for each open of this interface - int (*open)(void); - /// called for each close of this interface - int (*close)(void); -}; /** * Initialize the plugin system. * always succeeds or aborts */ void -lumiera_init_plugin (void); - +lumiera_pluginregistry_init (void); /** - * Make an interface available. - * To use an interface provided by a plugin it must be opened first. It is allowed to open an interface - * more than once. Each open must be paired with a close. - * @param name name of the plugin to use. - * @param interface name of the interface to open. - * @param min_revision the size of the interface structure is used as measure of a minimal required - * revision (new functions are appended at the end) - * @return handle to the interface or NULL in case of a error. The application shall cast this handle to - * the actual interface type. - */ -struct lumiera_interface* -lumiera_interface_open (const char* plugin, const char* name, size_t min_revision); - - -/** - * Close an interface. Does not free associated resources - * Calling this function with self==NULL is legal. Every interface handle must be closed only once. - * @param ptr interface to be closed + * destroy the plugin system, free all resources */ void -lumiera_interface_close (void* self); +lumiera_pluginregistry_destroy (void); + + +LumieraPlugin +lumiera_plugin_load (const char* plugin); + + +int +lumiera_plugin_register (LumieraPlugin); + + +/** + * discover new plugins + * traverses the configured plugin dirs and calls the callback_load function for any plugin + * not actually loaded. If callback_load returns a plugin (and not NULL) then this is feed to + * the callback_register function. + */ +int +lumiera_plugin_discover (LumieraPlugin (*callback_load)(const char* plugin), + int (*callback_register) (LumieraPlugin)); + + + + /** * Tries to unload a plugin. @@ -136,22 +93,5 @@ lumiera_interface_close (void* self); int lumiera_plugin_unload (const char* plugin); -/** - * Tries to unload plugins which are not in use. - * Calls lumiera_plugin_unload() for each Plugin which is not used for more than age seconds. - * This function might be infrequently called by the scheduler to remove things which are not needed. - * @param age timeout in seconds when to unload plugins - */ -void -lumiera_plugin_expire (time_t age); -LUMIERA_ERROR_DECLARE(PLUGIN_DLOPEN); -LUMIERA_ERROR_DECLARE(PLUGIN_HOOK); -LUMIERA_ERROR_DECLARE(PLUGIN_NFILE); -LUMIERA_ERROR_DECLARE(PLUGIN_NIFACE); -LUMIERA_ERROR_DECLARE(PLUGIN_REVISION); - -#ifdef __cplusplus -} /* extern "C" */ -#endif #endif /* LUMIERA_PLUGIN_H */