void PluginManager::destroyPlugin(Plugin &plugin) { const PluginInfo *info = findPluginInfo(plugin.id()); // Cache the plugin only if it can be reused later. if (info && info->cache) { plugin.addToCache(m_lruCachedPlugin, m_mruCachedPlugin); if (++m_nCachedPlugins > m_cacheSize) { Plugin *p = m_lruCachedPlugin; m_table.erase(p->id()); p->removeFromCache(m_lruCachedPlugin, m_mruCachedPlugin); --m_nCachedPlugins; // Defer destroying the plugin. g_idle_add_full(G_PRIORITY_LOW, destroyPluginDeferred, new std::pair<PluginManager *, Plugin *>(this, p), NULL); } } else // Defer destroying the plugin. g_idle_add_full(G_PRIORITY_LOW, destroyPluginDeferred, new std::pair<PluginManager *, Plugin *>(this, &plugin), NULL); }
Extension *PluginManager::acquireExtension(const char *extensionId) { std::string pluginId(extensionId, strrchr(extensionId, '/') - extensionId); PluginInfo *info = m_registry.find(pluginId.c_str())->second; // Retrieve the plugin if it is active, fetch the plugin from the cache if // it is cached or create it. Plugin *plugin; bool newPlugin; Table::const_iterator it = m_table.find(pluginId.c_str()); if (it != m_table.end()) { plugin = it->second; if (plugin->cached()) { plugin->removeFromCache(m_lruCachedPlugin, m_mruCachedPlugin); --m_nCachedPlugins; newPlugin = true; } else newPlugin = false; } else { char *module = g_module_build_path(m_modulesDirName.c_str(), info->module.c_str()); std::string error; plugin = Plugin::activate(*this, pluginId.c_str(), module, error); g_free(module); if (!plugin) { GtkWidget *dialog; dialog = gtk_message_dialog_new( NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Samoyed failed to activate plugin \"%s\"."), pluginId.c_str()); if (!error.empty()) Samoyed::gtkMessageDialogAddDetails( dialog, _("%s"), error.c_str()); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return NULL; } m_table.insert(std::make_pair(plugin->id(), plugin)); newPlugin = true; } // Acquire the extension from the plugin. Extension *ext = plugin->acquireExtension(extensionId); if (!ext && newPlugin) { plugin->addToCache(m_lruCachedPlugin, m_mruCachedPlugin); if (++m_nCachedPlugins > m_cacheSize) { Plugin *p = m_lruCachedPlugin; m_table.erase(p->id()); p->removeFromCache(m_lruCachedPlugin, m_mruCachedPlugin); --m_nCachedPlugins; // Defer destroying the plugin. g_idle_add_full(G_PRIORITY_LOW, destroyPluginDeferred, new std::pair<PluginManager *, Plugin *>(this, p), NULL); } } return ext; }