automatic plugin unloading at interfaceregistry_destroy()
All open plugins will be unloaded when the registry gets destroyed. If there are still interfaces open, this will assert at ALPHA builds.
This commit is contained in:
parent
240e7cb295
commit
c26cd391b0
4 changed files with 42 additions and 12 deletions
|
|
@ -106,7 +106,7 @@ lumiera_interfaceregistry_init (void)
|
|||
if (!lumiera_interfaceregistry)
|
||||
LUMIERA_DIE (ERRNO);
|
||||
|
||||
lumiera_pluginregistry = psplay_new (lumiera_plugin_cmp_fn, lumiera_plugin_key_fn, NULL);
|
||||
lumiera_pluginregistry = psplay_new (lumiera_plugin_cmp_fn, lumiera_plugin_key_fn, lumiera_plugin_delete_fn);
|
||||
if (!lumiera_pluginregistry)
|
||||
LUMIERA_DIE (ERRNO);
|
||||
|
||||
|
|
@ -118,20 +118,18 @@ void
|
|||
lumiera_interfaceregistry_destroy (void)
|
||||
{
|
||||
TRACE (interfaceregistry);
|
||||
REQUIRE (!psplay_nelements (lumiera_interfaceregistry));
|
||||
|
||||
lumiera_mutex_destroy (&lumiera_interface_mutex, &NOBUG_FLAG(interfaceregistry));
|
||||
|
||||
if (lumiera_interfaceregistry)
|
||||
psplay_destroy (lumiera_interfaceregistry);
|
||||
lumiera_interfaceregistry = NULL;
|
||||
|
||||
TODO ("provide a delete function for the psplay tree to tear it down");
|
||||
REQUIRE (psplay_nelements (lumiera_pluginregistry) == 0, "plugins still loaded at destroy");
|
||||
|
||||
if (lumiera_pluginregistry)
|
||||
psplay_delete (lumiera_pluginregistry);
|
||||
lumiera_pluginregistry = NULL;
|
||||
|
||||
lumiera_mutex_destroy (&lumiera_interface_mutex, &NOBUG_FLAG(interfaceregistry));
|
||||
|
||||
REQUIRE (!psplay_nelements (lumiera_interfaceregistry), "some interfaces still registered at shutdown");
|
||||
|
||||
if (lumiera_interfaceregistry)
|
||||
psplay_destroy (lumiera_interfaceregistry);
|
||||
lumiera_interfaceregistry = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -362,3 +362,31 @@ lumiera_plugin_key_fn (const PSplaynode node)
|
|||
return ((LumieraPlugin)node)->name;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lumiera_plugin_delete_fn (PSplaynode node)
|
||||
{
|
||||
LumieraPlugin self = (LumieraPlugin) node;
|
||||
|
||||
ENSURE (!self->refcnt, "plugin %s still in use at shutdown", self->name);
|
||||
|
||||
|
||||
const char* ext = strrchr (self->name, '.');
|
||||
|
||||
LumieraPlugintype itr = lumiera_plugin_types;
|
||||
while (itr->ext)
|
||||
{
|
||||
if (!strcmp (itr->ext, ext))
|
||||
{
|
||||
if (!self->error)
|
||||
{
|
||||
LUMIERA_INTERFACE_HANDLE(lumieraorg__plugin, 0) handle =
|
||||
LUMIERA_INTERFACE_CAST(lumieraorg__plugin, 0) self->plugin;
|
||||
lumiera_interfaceregistry_bulkremove_interfaces (handle->plugin_interfaces ());
|
||||
}
|
||||
itr->lumiera_plugin_unload_fn (self);
|
||||
break;
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,5 +174,7 @@ lumiera_plugin_cmp_fn (const void* keya, const void* keyb);
|
|||
const void*
|
||||
lumiera_plugin_key_fn (const PSplaynode node);
|
||||
|
||||
void
|
||||
lumiera_plugin_delete_fn (PSplaynode node);
|
||||
|
||||
#endif /* LUMIERA_PLUGIN_H */
|
||||
|
|
|
|||
|
|
@ -54,5 +54,7 @@ void
|
|||
lumiera_plugin_unload_DYNLIB (LumieraPlugin self)
|
||||
{
|
||||
TRACE (plugin);
|
||||
dlclose (lumiera_plugin_handle (self));
|
||||
void* handle = lumiera_plugin_handle (self);
|
||||
if (handle)
|
||||
dlclose (handle);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue