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.
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.                 * | 
