50 static LumieraInterfacenode
51 lumiera_interface_open_interfacenode (LumieraInterfacenode
self);
54 lumiera_interfacenode_close (LumieraInterfacenode
self);
60 LumieraInterfacenode
self = NULL;
61 TRACE (interface,
"%s", name);
62 WARN_IF (version == 0, interface,
"opening experimental interface: %s_%d_%s", interface, version, name);
66 self = lumiera_interfaceregistry_interfacenode_find (interface, version, name);
70 UNIMPLEMENTED (
"query plugindb and load plugin if exists");
75 if (minminorversion > self->interface->size)
77 UNIMPLEMENTED (
"set error");
82 self = lumiera_interface_open_interfacenode (
self);
86 return self->interface;
91 push_dependency (LumieraInterfacenode parent, LumieraInterfacenode child)
94 TRACE (interface_dbg,
"%s %s", parent->interface->name, child->interface->name);
97 if (!parent->deps_size)
98 parent->deps =
lumiera_calloc (parent->deps_size = 4, sizeof (LumieraInterfacenode));
100 size_t sz = parent->deps_size;
101 LumieraInterfacenode* itr = parent->deps;
110 sz = parent->deps_size + 1;
111 parent->deps_size *= 2;
112 parent->deps =
lumiera_realloc (parent->deps, parent->deps_size * sizeof (LumieraInterface));
113 itr = parent->deps + sz - 2;
114 memset (itr, 0, sz *
sizeof (LumieraInterface));
124 depwalk (LumieraInterfacenode
self, LumieraInterfacenode* stack)
129 TRACE (interface_dbg,
"%s %d", self->interface->name, self->refcnt);
130 for (LumieraInterfacenode* dep = self->deps; *dep; ++dep)
132 TRACE (interface_dbg,
"loop %s", (*dep)->interface->name);
134 for (LumieraInterfacenode itr = *stack; itr; itr = itr->lnk)
138 TRACE (interface_dbg,
"CYCLE");
149 (*dep)->lnk = *stack;
152 depwalk (*dep, stack);
154 *stack = (*dep)->lnk;
162 static LumieraInterfacenode
163 lumiera_interface_open_interfacenode (LumieraInterfacenode
self)
165 static unsigned collect_dependencies = 0;
166 static LumieraInterfacenode stack = NULL;
175 TRACE (interface_dbg,
"%s %d (%s)", self->interface->name, self->refcnt, stack?stack->interface->name:
"");
182 for (LumieraInterfacenode itr = stack; itr; itr = itr->lnk)
186 TRACE (interface_dbg,
"CYCLE");
193 if (collect_dependencies)
194 push_dependency (stack,
self);
204 int collect_dependencies_bak = collect_dependencies;
206 if (self->refcnt == 1)
209 if (self->interface->acquire)
211 TRACE (interface_dbg,
"Acquire %s", self->interface->name);
212 collect_dependencies =
self->deps?0:1;
219 collect_dependencies = 0;
220 depwalk (
self, &stack);
223 collect_dependencies = collect_dependencies_bak;
237 TRACE (interface_dbg);
241 lumiera_interfacenode_close ((LumieraInterfacenode)
psplay_find (lumiera_interfaceregistry,
self, 100));
249 if (
self && iname && !strcmp (self->interface, iname))
250 return self->version;
258 lumiera_interfacenode_close (LumieraInterfacenode
self)
260 static LumieraInterfacenode stack = NULL;
265 TRACE (interface,
"%s %d (%s)", self->interface->name, self->refcnt, stack?stack->interface->name:
"");
267 REQUIRE (self->refcnt);
271 for (LumieraInterfacenode itr = stack; itr; itr = itr->lnk)
275 TRACE (interface_dbg,
"CYCLE");
286 if (self->refcnt == 1)
288 if (self->interface->release)
290 TRACE (interface_dbg,
"Release %s", self->interface->name);
291 self->interface->release (self->interface);
298 TRACE (interface_dbg,
"Recurse %s %d", self->interface->name, self->refcnt);
300 for (LumieraInterfacenode* dep = self->deps; *dep; ++dep)
301 lumiera_interfacenode_close (*dep);
319 LUMIERA_INTERFACE_DEFINE (lumieraorg_interface, 0,
320 lumieraorg_interface,
324 LUMIERA_INTERFACE_MAP (open,
326 LUMIERA_INTERFACE_MAP (close,
328 LUMIERA_INTERFACE_MAP (version,
Portable and safe wrappers around some C-Lib functions.
void * lumiera_calloc(size_t n, size_t size)
Allocate cleared memory for an array.
#define LUMIERA_RECMUTEX_SECTION(nobugflag, mtx)
Recursive Mutual exclusive section.
void lumiera_interface_destroy(void)
deregistering implementations of the above interface
LumieraInterface lumiera_interface_open(const char *interface, unsigned version, size_t minminorversion, const char *name)
Open an interface by version and name.
LUMIERA_EXPORT(LUMIERA_INTERFACE_DEFINE(lumieraorg_interface, 0, lumieraorg_interface, NULL, NULL, NULL, LUMIERA_INTERFACE_MAP(open, lumiera_interface_open), LUMIERA_INTERFACE_MAP(close, lumiera_interface_close), LUMIERA_INTERFACE_MAP(version, lumiera_interface_version),))
Definition of 'the mother of all interfaces' since this interface is singleton and required for any c...
void lumiera_interface_init(void)
registering implementations of the above interface
Lumiera plugins define 'interfaces' as shown in interface.h, the plugin system handles the loading of...
unsigned lumiera_interface_version(LumieraInterface self, const char *iname)
Runtime check for interface type and version.
This header is for including and configuring NoBug.
Mutual exclusion locking, header.
PSplaynode psplay_find(PSplay self, const void *key, int splayfactor)
Find a element in a splay tree.
#define LUMIERA_INTERFACE_REGISTEREXPORTED
Register all exported interfaces when not a plugin This is a no-op when LUMIERA_PLUGIN is defined...
Lumiera interface macros and structures.
void lumiera_plugin_refinc(LumieraPlugin self)
void lumiera_interface_close(LumieraInterface self)
Close an interface after use.
void * lumiera_realloc(void *ptr, size_t size)
Change the size of a memory block.
Global registry for interfaces (extension points).
#define LUMIERA_INTERFACE_UNREGISTEREXPORTED
Unregister all exported interfaces when not a plugin This is a no-op when LUMIERA_PLUGIN is defined...
void lumiera_plugin_refdec(LumieraPlugin self)
LumieraInterface lumiera_interface_interface
the mother of all interfaces