Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
}