diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/pe/core.c | 15 | ||||
-rw-r--r-- | plugins/pychrysalide/bindings.c | 125 | ||||
-rw-r--r-- | plugins/pychrysalide/bindings.h | 14 | ||||
-rw-r--r-- | plugins/pychrysalide/core-ui.c | 3 | ||||
-rw-r--r-- | plugins/pychrysalide/core.c | 42 |
5 files changed, 103 insertions, 96 deletions
diff --git a/plugins/pe/core.c b/plugins/pe/core.c index 42f712d..9d30a34 100644 --- a/plugins/pe/core.c +++ b/plugins/pe/core.c @@ -62,8 +62,8 @@ static void g_pe_plugin_finalize(GPePlugin *); /* Prend acte de l'activation du greffon. */ static bool g_pe_plugin_enable(GPePlugin *); -/* Prend acte de l'extinction du greffon. */ -static void g_pe_plugin_disable(GPePlugin *); +/* Prend acte de la désactivation du greffon. */ +static bool g_pe_plugin_disable(GPePlugin *); @@ -288,16 +288,21 @@ static bool g_pe_plugin_enable(GPePlugin *plugin) * * * Paramètres : plugin = greffon à manipuler. * * * -* Description : Prend acte de l'extinction du greffon. * +* Description : Prend acte de la désactivation du greffon. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static void g_pe_plugin_disable(GPePlugin *plugin) +static bool g_pe_plugin_disable(GPePlugin *plugin) { + bool result; /* Bilan à retourner */ + + result = true; + + return result; } diff --git a/plugins/pychrysalide/bindings.c b/plugins/pychrysalide/bindings.c index 02850d1..99491d6 100644 --- a/plugins/pychrysalide/bindings.c +++ b/plugins/pychrysalide/bindings.c @@ -25,16 +25,15 @@ #include "bindings.h" -#ifdef PYTHON_PACKAGE -# include <dlfcn.h> -#endif +#include <assert.h> +#include <dlfcn.h> #include <pygobject.h> #include <stdio.h> -#include <config.h> #include <common/cpp.h> #include <common/extstr.h> +#include <core/core.h> #include <plugins/pglist.h> #include <plugins/self.h> @@ -125,6 +124,8 @@ static void restore_original_pygobject_type(PyTypeObject *); /* ------------------------ FONCTIONS GLOBALES DE CHRYSALIDE ------------------------ */ +/* Assure le plein chargement dans un interpréteur Python. */ +static bool init_python_interpreter_for_standalone_mode(const pyinit_details_t *); /* Point de sortie pour l'initialisation de Python. */ static void PyExit_pychrysalide(void); @@ -915,7 +916,7 @@ PyObject *init_python_pychrysalide_module(const pyinit_details_t *details) PyErr_SetString(PyExc_SystemError, "failed to load all PyChrysalide components."); else if (details->standalone) - status = do_global_init(); + status = init_python_interpreter_for_standalone_mode(details); if (!status) { @@ -1060,13 +1061,11 @@ void log_pychrysalide_exception(const char *prefix, ...) /* ---------------------------------------------------------------------------------- */ - - /****************************************************************************** * * -* Paramètres : py_gobj_def = définition de type actuelle. [OUT] * +* Paramètres : details = précisions de chargement complémentaires. * * * -* Description : Restore une ancienne définition de type GObject au besoin. * +* Description : Assure le plein chargement dans un interpréteur Python. * * * * Retour : Bilan de l'opération. * * * @@ -1074,103 +1073,77 @@ void log_pychrysalide_exception(const char *prefix, ...) * * ******************************************************************************/ -bool do_global_init(void) +static bool init_python_interpreter_for_standalone_mode(const pyinit_details_t *details) { - - return true; - return false; - - -#if 0 - - bool result; /* Bilan à retourner */ int ret; /* Bilan de préparatifs */ -#ifdef PYTHON_PACKAGE Dl_info info; /* Informations dynamiques */ -#endif + GModule *module; /* Structure de chargement GLib*/ GPluginModule *self; /* Représentation interne */ - PluginStatusFlags self_flags; /* Fanions à mettre à jour */ + + result = false; ret = Py_AtExit(PyExit_pychrysalide); if (ret == -1) { PyErr_SetString(PyExc_SystemError, "failed to register a cleanup function."); - goto exit_and_restore; + goto exit; + } + + if (!load_core_components(ACC_ALL_COMPONENTS)) + { + PyErr_SetString(PyExc_SystemError, "unable to load core components."); + goto exit; } /** - * Si cette extension pour Python est chargée depuis un dépôt Python, - * elle ne se trouve pas dans le répertoire classique des extensions et - * n'est donc pas chargée et enregistrée comme attendu. + * Le module chargé par Python n'apparaît pas dans la liste des greffons de + * Chrysalide et ne peut donc pas être référencé comme dépendance par d'autres + * extensions. * - * Cet enregistrement est donc forcé ici. + * Par ailleurs, lors de la recherche d'autres greffons via l'appel à la + * fonction init_all_plugins() ci-après, il faut que le nom du greffon soit + * déjà réservé pour faire échouer le second chargement du greffon courant + * lors du parcours des répertoires conservant les fichiers d'extensions. */ -#ifdef PYTHON_PACKAGE - ret = dladdr(__FUNCTION__, &info); if (ret == 0) { LOG_ERROR_DL_N("dladdr"); - - // err msg - - - Py_DECREF(result); - result = NULL; - - goto exit_and_restore; - } - - self = g_plugin_module_new(info.dli_fname); - assert(self != NULL); - - register_plugin(self); - -#endif - - - if (!load_core_components(ACC_GLOBAL_VARS)) - { - PyErr_SetString(PyExc_SystemError, "unable to load core components."); + PyErr_SetString(PyExc_SystemError, "failed to force bindings registration."); goto exit; - } - init_all_plugins(false); + } - lock_plugin_list_for_reading(); + module = g_module_open(info.dli_fname, G_MODULE_BIND_LAZY); + assert(module != NULL); - self = get_plugin_by_name("PyChrysalide", NULL); - assert(self != NULL); + self = details->create_self(module); - self_flags = g_plugin_module_get_flags(self); - self_flags &= ~(PSF_FAILURE | PSF_LOADED); - self_flags |= (status ? PSF_LOADED : PSF_FAILURE); + /* A ce stade, le greffon a été chargé correctement */ + g_plugin_module_override_flags(self, PSF_LOADED); - g_plugin_module_override_flags(self, self_flags); + register_plugin(self); unref_object(self); - unlock_plugin_list_for_reading(); - - load_remaning_plugins(); - - + /** + * Intégration des fonctionnalités portées par d'autres greffons. + */ + result = true; + init_all_plugins(true); - done: + exit: return result; -#endif - } - /****************************************************************************** * * * Paramètres : - * @@ -1185,24 +1158,8 @@ bool do_global_init(void) static void PyExit_pychrysalide(void) { - //assert(_standalone); - - /* - extern void set_current_project(void *project); - - set_current_project(NULL); - */ - -#ifdef TRACK_GOBJECT_LEAKS - remember_gtypes_for_leaks(); -#endif - exit_all_plugins(); - //unload_all_core_components(true); - -#ifdef TRACK_GOBJECT_LEAKS - dump_remaining_gtypes(); -#endif + unload_core_components(ACC_ALL_COMPONENTS); } diff --git a/plugins/pychrysalide/bindings.h b/plugins/pychrysalide/bindings.h index e9ee421..1758747 100644 --- a/plugins/pychrysalide/bindings.h +++ b/plugins/pychrysalide/bindings.h @@ -36,9 +36,13 @@ #include <Python.h> +#include <gmodule.h> #include <stdbool.h> +#include <plugins/plugin.h> + + /* Charge un module GI dans Python avec une version attendue. */ bool import_namespace_from_gi_repository(const char *, const char *); @@ -50,6 +54,12 @@ typedef struct _pyinit_details_t bool (* populate_extra) (void); /* Ajout de types ? */ + /** + * Prototype de la fonction de création, à garder synchronisé avec + * NATIVE_PLUGIN_ENTRYPOINT() (cf. native-int.h). + */ + GPluginModule * (* create_self) (GModule *); + } pyinit_details_t; /* Implémente le point d'entrée pour l'initialisation de Python. */ @@ -60,8 +70,4 @@ void log_pychrysalide_exception(const char *, ...); -bool do_global_init(void); - - - #endif /* _PLUGINS_PYCHRYSALIDE_BINDINGS_H */ diff --git a/plugins/pychrysalide/core-ui.c b/plugins/pychrysalide/core-ui.c index 32d3516..1b332b7 100644 --- a/plugins/pychrysalide/core-ui.c +++ b/plugins/pychrysalide/core-ui.c @@ -179,7 +179,7 @@ GPluginModule *g_pychrysalide_plugin_ui_new(GModule *module) { GPyChrysalidePluginUI *result; /* Structure à retourner */ - result = g_object_new(G_TYPE_PYCHRYSALIDE_PLUGIN, NULL); + result = g_object_new(G_TYPE_PYCHRYSALIDE_PLUGIN_UI, NULL); if (!g_pychrysalide_plugin_ui_create(result, module)) g_clear_object(&result); @@ -310,6 +310,7 @@ PyMODINIT_FUNC PyInit_pychrysalideui(void) details.standalone = _standalone; details.populate_extra = NULL; + details.create_self = g_pychrysalide_plugin_ui_new; result = init_python_pychrysalide_module(&details); diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c index fde1028..0e72b46 100644 --- a/plugins/pychrysalide/core.c +++ b/plugins/pychrysalide/core.c @@ -390,16 +390,53 @@ static bool g_pychrysalide_plugin_enable(GPyChrysalidePlugin *plugin) static bool g_pychrysalide_plugin_disable(GPyChrysalidePlugin *plugin) { + bool result; /* Bilan à retourner */ + bool standalone; /* Nature du chargement */ PyGILState_STATE gstate; /* Sauvegarde d'environnement */ - gstate = PyGILState_Ensure(); + result = true; + + /** + * Le champ plugin->py_module n'est défini que via la fonction + * g_pychrysalide_plugin_enable(), qui n'est pas sollicitée lorsque + * le module PyChrysalide est mis en place directement par Python. + * + * L'analyse de ce champ pour retrouver la situation courante est + * plus fiable que celle du champ _standalone, potentiellement + * cohérent dans la version UI du greffon et resté à son état + * initial ici. + */ + + standalone = (plugin->py_module == NULL); + + /** + * Si on se trouve embarqué dans un interpréteur Python, le déchargement + * des greffons est organisé à partir de la fonction PyExit_pychrysalide(), + * directement appelée depuis un contexte Python. + * + * Un verrou n'est alors pas souhaité ici : + * + * python3d: ../Python/pystate.c:1687: PyGILState_Ensure: Assertion `gilstate->autoInterpreterState' failed. + * + * Avec : + * + * $ python3d --version + * Python 3.11.2 + * + */ + + if (!standalone) + gstate = PyGILState_Ensure(); clear_all_accesses_to_python_modules(); Py_XDECREF(plugin->py_module); plugin->py_module = NULL; - PyGILState_Release(gstate); + if (!standalone) + PyGILState_Release(gstate); + + return result; } @@ -720,6 +757,7 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) details.standalone = _standalone; details.populate_extra = NULL; + details.create_self = g_pychrysalide_plugin_new; result = init_python_pychrysalide_module(&details); |