diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2025-01-16 01:00:28 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2025-01-16 01:00:28 (GMT) |
commit | 64b690f0038e01e807c1ec8d62041057fd38b4b8 (patch) | |
tree | 1de592f2379547abfb8aedc452958dbdace9b658 /src/plugins/pglist.c | |
parent | 8be5b3fb8a516380fc88fd900a98238ce8564682 (diff) |
Improve the plugins management.gtk4
Diffstat (limited to 'src/plugins/pglist.c')
-rw-r--r-- | src/plugins/pglist.c | 144 |
1 files changed, 81 insertions, 63 deletions
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c index 277e4f5..6dc2d9c 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 - } @@ -485,6 +441,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 +449,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 +608,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 +646,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 +674,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 +689,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. * |