diff options
Diffstat (limited to 'src/plugins/pglist.c')
-rw-r--r-- | src/plugins/pglist.c | 172 |
1 files changed, 82 insertions, 90 deletions
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c index 277e4f5..3e107b8 100644 --- a/src/plugins/pglist.c +++ b/src/plugins/pglist.c @@ -37,9 +37,10 @@ #include "manager.h" +#include "native.h" #include "plugin-int.h" #include "../common/cpp.h" -#include "../common/extstr.h" // REMME ? +#include "../common/extstr.h" #include "../core/logs.h" #include "../core/nox.h" #include "../core/paths.h" @@ -69,6 +70,9 @@ static void browse_directory_for_plugins(const char *); /* Suit les variations du compteur de références d'un greffon. */ static void on_plugin_ref_toggle(gpointer, GPluginModule *, gboolean); +/* Fournit le greffon répondant à un nom donné. */ +static GPluginModule *_find_plugin_by_name(const char *, size_t *); + /****************************************************************************** @@ -134,71 +138,23 @@ bool init_all_plugins(bool load) void exit_all_plugins(void) { - -#if 0 ////// - - size_t i; /* Boucle de parcours */ - const plugin_interface *pg_iface; /* Définition du greffon */ lock_plugin_list_for_reading(); - if (_pg_list != NULL) + for (i = 0; i < _pg_count; i++) { - for (i = 0; i < _pg_count; i++) - { - assert(_pg_list[i] != NULL); - - /** - * Si le greffon a conduit à la mise en place d'autres greffons, le - * système de dépendances ne suffit pas pour le décompte des références : - * le greffon voit à un instant T son compteur décroître ici ; à un - * instant T+1, un greffon fils décrémente à son tour le compteur vers - * le greffon principal. - * - * Le compteur du conteneur tombe alors à 0, et le code correspondant - * est retiré. Lorsque que le flot d'exécution revient à la procédure - * de sortie du second greffon, son code n'est plus en mémoire. - * - * On s'assure donc que les greffons qui génèrent d'autres greffons - * sont bien traités en dernier. - */ - - pg_iface = g_plugin_module_get_interface(_pg_list[i]); - - if (pg_iface != NULL && pg_iface->container) - g_object_ref(_pg_list[i]); - - g_object_unref(_pg_list[i]); - - } - - for (i = 0; i < _pg_count; i++) - { - if (_pg_list[i] == NULL) - continue; - - pg_iface = g_plugin_module_get_interface(_pg_list[i]); - - if (pg_iface == NULL || !pg_iface->container) - continue; - - g_object_unref(_pg_list[i]); - - } + assert(_pg_list[i] != NULL); + unref_object(_pg_list[i]); + } + if (_pg_list != NULL) free(_pg_list); - } - unlock_plugin_list_for_reading(); g_rw_lock_clear(&_pg_lock); - - -#endif - } @@ -388,22 +344,10 @@ static void browse_directory_for_plugins(const char *dir) else { - - printf("// Candidate // %s\n", filename); - has_alt = check_for_plugin_versions(dir, namelist[k]->d_name, &is_nox, &is_ui); - printf(" -> nox=%d ui=%d -> alt? %d\n", is_nox, is_ui, has_alt); - - if ((nox_mode && is_nox) || (!nox_mode && ((is_nox && !has_alt) || is_ui))) { - - - printf(" ---> load!\n"); - - - module = g_module_open(filename, G_MODULE_BIND_LAZY); if (module == NULL) { @@ -413,32 +357,18 @@ static void browse_directory_for_plugins(const char *dir) goto next_file; } - - printf(" (main) module=%p '%s'\n", module, g_module_name(module)); - + get_instance = NULL; if (!g_module_symbol(module, "get_chrysalide_plugin_instance", (gpointer *)&get_instance)) - { log_variadic_message(LMT_ERROR, _("No '%s' entry in plugin candidate '%s'"), "<sym>", filename); - - - } - - if (get_instance == NULL) plugin = NULL; else plugin = get_instance(module); - - - printf(" ===> plugin: %p\n", plugin); - - - if (plugin != NULL) { register_plugin(plugin); @@ -485,6 +415,7 @@ static void on_plugin_ref_toggle(gpointer unused, GPluginModule *plugin, gboolea const char *name; /* Désignation du greffon */ size_t index; /* Indice du greffon */ GPluginModule *same; /* Juste pour la récupération */ + GModule *module; /* Structure de chargement GLib*/ if (last) { @@ -492,15 +423,44 @@ static void on_plugin_ref_toggle(gpointer unused, GPluginModule *plugin, gboolea name = g_plugin_module_get_name(plugin); - same = get_plugin_by_name(name, &index); + /** + * Les mécanismes de g_object_unref() prennent en compte la bascule d'un + * compteur de références initialement à 2 avant appel pour déclencher + * cet appel à on_plugin_ref_toggle() mis en place par g_object_add_toggle_ref(). + * + * Incrémenter ce compteur à nouveau, via get_plugin_by_name(), puis le + * décrémenter ensuite via unref_object() va conduire à une nouvelle + * bascule des statuts de suivi dans g_object_unref(). + * + * Il est ainsi impératif de rechercher une instance du greffon dans + * la liste des extensions sans toucher au compteur de références. + */ + + same = _find_plugin_by_name(name, &index); + assert(same != NULL); assert(same == plugin); - g_clear_object(&_pg_list[index]); + _pg_list[index] = NULL; + + /** + * Suppression de la dernière référence. + */ + + if (G_IS_NATIVE_PLUGIN(plugin)) + module = g_native_plugin_get_module(G_NATIVE_PLUGIN(plugin)); + else + module = NULL; g_object_remove_toggle_ref(G_OBJECT(same), (GToggleNotify)on_plugin_ref_toggle, NULL); - unref_object(same); + /** + * Plus aucun code issu du greffon n'est désormais utile. Le module associé peut + * être libéré de la mémoire. + */ + + if (module != NULL) + g_module_close(module); } @@ -622,13 +582,18 @@ void load_remaning_plugins(void) /* Supprime les greffons non chargés */ - for (i = 0; i < _pg_count; i++) + for (i = 0; i < _pg_count;) { flags = g_plugin_module_get_flags(_pg_list[i]); - if ((flags & PSF_LOADED) == 0) + if (flags & PSF_LOADED) + i++; + + else { - g_object_unref(G_OBJECT(_pg_list[i])); + unref_object(_pg_list[i]); + + assert(_pg_list[i] == NULL); memmove(&_pg_list[i], &_pg_list[i + 1], (_pg_count - i - 1) * sizeof(GPluginModule *)); _pg_count--; @@ -655,11 +620,12 @@ void load_remaning_plugins(void) * * * Retour : Instance du greffon trouvé ou NULL si aucun. * * * -* Remarques : - * +* Remarques : Le compteur de référence d'un greffon trouvé n'est pas * +* modifié. * * * ******************************************************************************/ -GPluginModule *get_plugin_by_name(const char *name, size_t *index) +static GPluginModule *_find_plugin_by_name(const char *name, size_t *index) { GPluginModule *result; /* Greffon trouvé à renvoyer */ size_t i; /* Boucle de parcours */ @@ -682,7 +648,6 @@ GPluginModule *get_plugin_by_name(const char *name, size_t *index) if (strcmp(current, name) == 0) { result = _pg_list[i]; - ref_object(result); if (index != NULL) *index = i; @@ -698,6 +663,33 @@ GPluginModule *get_plugin_by_name(const char *name, size_t *index) /****************************************************************************** * * +* Paramètres : name = désignation du greffon recherché. * +* index = indice du greffon trouvé. [OUT] * +* * +* Description : Fournit le greffon répondant à un nom donné. * +* * +* Retour : Instance du greffon trouvé ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GPluginModule *get_plugin_by_name(const char *name, size_t *index) +{ + GPluginModule *result; /* Greffon trouvé à renvoyer */ + + result = _find_plugin_by_name(name, index); + + if (result != NULL) + ref_object(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : count = nombre de greffons trouvés. [OUT] * * * * Description : Fournit la liste de l'ensemble des greffons. * |