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:
Christian Thaeter 2008-11-05 09:47:52 +01:00
parent 240e7cb295
commit c26cd391b0
4 changed files with 42 additions and 12 deletions

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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 */

View file

@ -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);
}