WIP: new plugin.h header
This ditches the old 'proof of concept' implementation, interfaces and plugins are internally separate now and publically only accessed over the 'interfaces' api. The interface registry now gets an additional 'plugin' member to backreference plugins from interfaces.
This commit is contained in:
parent
7be18d6344
commit
48778cf3d7
3 changed files with 52 additions and 104 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "lib/psplay.h"
|
||||
|
||||
#include "backend/interface.h"
|
||||
#include "backend/plugin.h"
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 <stdlib.h>
|
||||
#include <nobug.h>
|
||||
|
||||
#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 */
|
||||
|
|
|
|||
Loading…
Reference in a new issue