41 static LumieraInterfacenode
42 lumiera_interface_open_interfacenode (LumieraInterfacenode
self);
45 lumiera_interfacenode_close (LumieraInterfacenode
self);
51 LumieraInterfacenode
self = NULL;
52 TRACE (interface,
"%s", name);
53 WARN_IF (version == 0, interface,
"opening experimental interface: %s_%d_%s", interface, version, name);
57 self = lumiera_interfaceregistry_interfacenode_find (interface, version, name);
61 UNIMPLEMENTED (
"query plugindb and load plugin if exists");
66 if (minminorversion > self->interface->size)
68 UNIMPLEMENTED (
"set error");
73 self = lumiera_interface_open_interfacenode (
self);
77 return self->interface;
82 push_dependency (LumieraInterfacenode parent, LumieraInterfacenode child)
85 TRACE (interface_dbg,
"%s %s", parent->interface->name, child->interface->name);
88 if (!parent->deps_size)
89 parent->deps =
lumiera_calloc (parent->deps_size = 4, sizeof (LumieraInterfacenode));
91 size_t sz = parent->deps_size;
92 LumieraInterfacenode* itr = parent->deps;
101 sz = parent->deps_size + 1;
102 parent->deps_size *= 2;
103 parent->deps =
lumiera_realloc (parent->deps, parent->deps_size * sizeof (LumieraInterface));
104 itr = parent->deps + sz - 2;
105 memset (itr, 0, sz *
sizeof (LumieraInterface));
115 depwalk (LumieraInterfacenode
self, LumieraInterfacenode* stack)
120 TRACE (interface_dbg,
"%s %d", self->interface->name, self->refcnt);
121 for (LumieraInterfacenode* dep = self->deps; *dep; ++dep)
123 TRACE (interface_dbg,
"loop %s", (*dep)->interface->name);
125 for (LumieraInterfacenode itr = *stack; itr; itr = itr->lnk)
129 TRACE (interface_dbg,
"CYCLE");
140 (*dep)->lnk = *stack;
143 depwalk (*dep, stack);
145 *stack = (*dep)->lnk;
153 static LumieraInterfacenode
154 lumiera_interface_open_interfacenode (LumieraInterfacenode
self)
156 static unsigned collect_dependencies = 0;
157 static LumieraInterfacenode stack = NULL;
166 TRACE (interface_dbg,
"%s %d (%s)", self->interface->name, self->refcnt, stack?stack->interface->name:
"");
173 for (LumieraInterfacenode itr = stack; itr; itr = itr->lnk)
177 TRACE (interface_dbg,
"CYCLE");
184 if (collect_dependencies)
185 push_dependency (stack,
self);
195 int collect_dependencies_bak = collect_dependencies;
197 if (self->refcnt == 1)
200 if (self->interface->acquire)
202 TRACE (interface_dbg,
"Acquire %s", self->interface->name);
203 collect_dependencies =
self->deps?0:1;
210 collect_dependencies = 0;
211 depwalk (
self, &stack);
214 collect_dependencies = collect_dependencies_bak;
228 TRACE (interface_dbg);
232 lumiera_interfacenode_close ((LumieraInterfacenode)
psplay_find (lumiera_interfaceregistry,
self, 100));
240 if (
self && iname && !strcmp (self->interface, iname))
241 return self->version;
249 lumiera_interfacenode_close (LumieraInterfacenode
self)
251 static LumieraInterfacenode stack = NULL;
256 TRACE (interface,
"%s %d (%s)", self->interface->name, self->refcnt, stack?stack->interface->name:
"");
258 REQUIRE (self->refcnt);
262 for (LumieraInterfacenode itr = stack; itr; itr = itr->lnk)
266 TRACE (interface_dbg,
"CYCLE");
277 if (self->refcnt == 1)
279 if (self->interface->release)
281 TRACE (interface_dbg,
"Release %s", self->interface->name);
282 self->interface->release (self->interface);
289 TRACE (interface_dbg,
"Recurse %s %d", self->interface->name, self->refcnt);
291 for (LumieraInterfacenode* dep = self->deps; *dep; ++dep)
292 lumiera_interfacenode_close (*dep);
310 LUMIERA_INTERFACE_DEFINE (lumieraorg_interface, 0,
311 lumieraorg_interface,
315 LUMIERA_INTERFACE_MAP (open,
317 LUMIERA_INTERFACE_MAP (close,
319 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