summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2022-08-18 19:05:33 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2022-08-18 19:05:33 (GMT)
commitf22f73bcbdb6510169c8b7c7c3fea842750c6fe5 (patch)
treec621257695d9f132dff88b9149ee86d3b0888236
parent429b54556283116a29c5d699af0cf891bb1c1055 (diff)
Handle the Python Global Interpreter Lock with more care.
-rw-r--r--plugins/pychrysalide/analysis/type.c30
-rw-r--r--plugins/pychrysalide/core.c67
-rw-r--r--plugins/pychrysalide/core.h3
-rw-r--r--plugins/pychrysalide/format/symbol.c5
-rw-r--r--plugins/pychrysalide/gui/item.c60
-rw-r--r--plugins/pychrysalide/helpers.c2
6 files changed, 77 insertions, 90 deletions
diff --git a/plugins/pychrysalide/analysis/type.c b/plugins/pychrysalide/analysis/type.c
index 86a0ffb..357d381 100644
--- a/plugins/pychrysalide/analysis/type.c
+++ b/plugins/pychrysalide/analysis/type.c
@@ -220,6 +220,7 @@ static void py_data_type_init_gclass(GDataTypeClass *class, gpointer unused)
static guint py_data_type_hash_wrapper(const GDataType *type)
{
guint result; /* Empreinte à renvoyer */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *pyret; /* Bilan de consultation */
@@ -234,6 +235,8 @@ static guint py_data_type_hash_wrapper(const GDataType *type)
result = 0;
+ gstate = PyGILState_Ensure();
+
pyobj = pygobject_new(G_OBJECT(type));
if (has_python_method(pyobj, "_hash"))
@@ -252,6 +255,8 @@ static guint py_data_type_hash_wrapper(const GDataType *type)
Py_DECREF(pyobj);
+ PyGILState_Release(gstate);
+
return result;
}
@@ -272,6 +277,7 @@ static guint py_data_type_hash_wrapper(const GDataType *type)
static GDataType *py_data_type_dup_wrapper(const GDataType *type)
{
GDataType *result; /* Copie à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *pyret; /* Bilan de consultation */
@@ -287,6 +293,8 @@ static GDataType *py_data_type_dup_wrapper(const GDataType *type)
result = NULL;
+ gstate = PyGILState_Ensure();
+
pyobj = pygobject_new(G_OBJECT(type));
if (has_python_method(pyobj, "_dup"))
@@ -308,6 +316,8 @@ static GDataType *py_data_type_dup_wrapper(const GDataType *type)
Py_DECREF(pyobj);
+ PyGILState_Release(gstate);
+
return result;
}
@@ -329,6 +339,7 @@ static GDataType *py_data_type_dup_wrapper(const GDataType *type)
static char *py_data_type_to_string_wrapper(const GDataType *type, bool include)
{
char *result; /* Etiquette à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *arg; /* Version Python de l'argument*/
PyObject *args; /* Arguments pour l'appel */
@@ -349,6 +360,8 @@ static char *py_data_type_to_string_wrapper(const GDataType *type, bool include)
result = NULL;
+ gstate = PyGILState_Ensure();
+
pyobj = pygobject_new(G_OBJECT(type));
if (has_python_method(pyobj, "_to_string"))
@@ -375,6 +388,8 @@ static char *py_data_type_to_string_wrapper(const GDataType *type, bool include)
Py_DECREF(pyobj);
+ PyGILState_Release(gstate);
+
return result;
}
@@ -395,6 +410,7 @@ static char *py_data_type_to_string_wrapper(const GDataType *type, bool include)
static bool py_data_type_handle_namespaces_wrapper(const GDataType *type)
{
bool result; /* Bilan à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *pyret; /* Bilan de consultation */
@@ -411,6 +427,8 @@ static bool py_data_type_handle_namespaces_wrapper(const GDataType *type)
result = true;
+ gstate = PyGILState_Ensure();
+
pyobj = pygobject_new(G_OBJECT(type));
if (has_python_method(pyobj, "_handle_namespaces"))
@@ -425,6 +443,8 @@ static bool py_data_type_handle_namespaces_wrapper(const GDataType *type)
Py_DECREF(pyobj);
+ PyGILState_Release(gstate);
+
return result;
}
@@ -445,6 +465,7 @@ static bool py_data_type_handle_namespaces_wrapper(const GDataType *type)
static bool py_data_type_is_pointer_wrapper(const GDataType *type)
{
bool result; /* Bilan à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *pyret; /* Bilan de consultation */
@@ -461,6 +482,8 @@ static bool py_data_type_is_pointer_wrapper(const GDataType *type)
result = false;
+ gstate = PyGILState_Ensure();
+
pyobj = pygobject_new(G_OBJECT(type));
if (has_python_method(pyobj, "_is_pointer"))
@@ -475,6 +498,8 @@ static bool py_data_type_is_pointer_wrapper(const GDataType *type)
Py_DECREF(pyobj);
+ PyGILState_Release(gstate);
+
return result;
}
@@ -495,6 +520,7 @@ static bool py_data_type_is_pointer_wrapper(const GDataType *type)
static bool py_data_type_is_reference_wrapper(const GDataType *type)
{
bool result; /* Bilan à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *pyret; /* Bilan de consultation */
@@ -511,6 +537,8 @@ static bool py_data_type_is_reference_wrapper(const GDataType *type)
result = false;
+ gstate = PyGILState_Ensure();
+
pyobj = pygobject_new(G_OBJECT(type));
if (has_python_method(pyobj, "_is_reference"))
@@ -525,6 +553,8 @@ static bool py_data_type_is_reference_wrapper(const GDataType *type)
Py_DECREF(pyobj);
+ PyGILState_Release(gstate);
+
return result;
}
diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c
index ef119fb..c062d15 100644
--- a/plugins/pychrysalide/core.c
+++ b/plugins/pychrysalide/core.c
@@ -85,9 +85,6 @@ static bool _standalone = true;
/* Réceptacle pour le chargement forcé */
static PyObject *_chrysalide_module = NULL;
-/* Conservation des informations du thread principal */
-static PyThreadState *_main_tstate = NULL;
-
/* Fournit la révision du programme global. */
static PyObject *py_chrysalide_revision(PyObject *, PyObject *);
@@ -656,7 +653,6 @@ static void load_python_plugins(GPluginModule *plugin)
struct dirent *entry; /* Elément trouvé */
char *modname; /* Nom du module pour Python */
char *filename; /* Chemin d'accès reconstruit */
- PyThreadState *tstate; /* Contexte d'environnement */
GPluginModule *pyplugin; /* Lien vers un grffon Python */
bool status; /* Bilan d'une opération */
GGenConfig *config; /* Configuration à charger */
@@ -736,17 +732,8 @@ static void load_python_plugins(GPluginModule *plugin)
filename = stradd(filename, G_DIR_SEPARATOR_S);
filename = stradd(filename, entry->d_name);
- if (!_standalone)
- {
- tstate = get_pychrysalide_main_tstate();
- PyEval_RestoreThread(tstate);
- }
-
pyplugin = g_python_plugin_new(modname, filename);
- if (!_standalone)
- PyEval_SaveThread();
-
if (pyplugin == NULL)
{
g_plugin_module_log_variadic_message(plugin, LMT_ERROR,
@@ -808,6 +795,7 @@ static void load_python_plugins(GPluginModule *plugin)
G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
{
bool result; /* Bilan à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
int ret; /* Bilan de préparatifs */
_standalone = false;
@@ -825,6 +813,8 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
Py_Initialize();
+ gstate = PyGILState_Ensure();
+
PySys_SetArgv(0, (wchar_t *[]) { NULL });
_chrysalide_module = PyImport_ImportModule("pychrysalide");
@@ -842,9 +832,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
result = (_chrysalide_module != NULL);
- _main_tstate = PyThreadState_Get();
-
- PyEval_ReleaseLock();
+ PyGILState_Release(gstate);
cpi_done:
@@ -867,10 +855,16 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
G_MODULE_EXPORT void chrysalide_plugin_exit(GPluginModule *plugin)
{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+
+ gstate = PyGILState_Ensure();
+
clear_all_accesses_to_python_modules();
Py_XDECREF(_chrysalide_module);
+ PyGILState_Release(gstate);
+
}
@@ -911,6 +905,7 @@ static void free_native_plugin_type(PyTypeObject *type)
G_MODULE_EXPORT void chrysalide_plugin_on_plugins_loaded(GPluginModule *plugin, PluginAction action)
{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
size_t count; /* Quantité de greffons chargés*/
PyTypeObject *parent; /* Type Python pour greffon */
PyObject *module; /* Module à recompléter */
@@ -922,6 +917,8 @@ G_MODULE_EXPORT void chrysalide_plugin_on_plugins_loaded(GPluginModule *plugin,
int ret; /* Bilan d'un appel */
PyTypeObject *type; /* Nouveau type dynamique */
+ gstate = PyGILState_Ensure();
+
if (action == PGA_NATIVE_PLUGINS_LOADED)
{
/* Intégration des greffons natifs en Python */
@@ -982,6 +979,8 @@ G_MODULE_EXPORT void chrysalide_plugin_on_plugins_loaded(GPluginModule *plugin,
}
+ PyGILState_Release(gstate);
+
}
@@ -1002,17 +1001,13 @@ G_MODULE_EXPORT void chrysalide_plugin_on_plugins_loaded(GPluginModule *plugin,
G_MODULE_EXPORT gpointer chrysalide_plugin_build_type_instance(GPluginModule *plugin, PluginAction action, GType type)
{
gpointer result; /* Instance à retourner */
- PyThreadState *tstate; /* Contexte d'environnement */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyTypeObject *pytype; /* Classe Python concernée */
PyObject *instance; /* Initialisation forcée */
result = NULL;
- if (!_standalone)
- {
- tstate = get_pychrysalide_main_tstate();
- PyEval_RestoreThread(tstate);
- }
+ gstate = PyGILState_Ensure();
pytype = pygobject_lookup_class(type);
@@ -1025,31 +1020,7 @@ G_MODULE_EXPORT gpointer chrysalide_plugin_build_type_instance(GPluginModule *pl
}
- if (!_standalone)
- PyEval_SaveThread();
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : - *
-* *
-* Description : Fournit les informations du thread principal. *
-* *
-* Retour : Indications utiles à Python. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-PyThreadState *get_pychrysalide_main_tstate(void)
-{
- PyThreadState *result; /* Indications à retourner */
-
- result = _main_tstate;
+ PyGILState_Release(gstate);
return result;
@@ -1078,6 +1049,8 @@ void log_pychrysalide_exception(const char *prefix, ...)
PyObject *err_string; /* Description Python d'erreur */
const char *err_msg; /* Représentation humaine */
+ assert(PyGILState_Check() == 1);
+
if (PyErr_Occurred())
{
/* Base de la communication */
diff --git a/plugins/pychrysalide/core.h b/plugins/pychrysalide/core.h
index 6a7b9d1..88c4140 100644
--- a/plugins/pychrysalide/core.h
+++ b/plugins/pychrysalide/core.h
@@ -55,9 +55,6 @@ G_MODULE_EXPORT void chrysalide_plugin_on_plugins_loaded(GPluginModule *, Plugin
/* Crée une instance à partir d'un type dynamique externe. */
G_MODULE_EXPORT gpointer chrysalide_plugin_build_type_instance(GPluginModule *, PluginAction, GType);
-/* Fournit les informations du thread principal. */
-PyThreadState *get_pychrysalide_main_tstate(void);
-
/* Présente dans le journal une exception survenue. */
void log_pychrysalide_exception(const char *, ...);
diff --git a/plugins/pychrysalide/format/symbol.c b/plugins/pychrysalide/format/symbol.c
index e2f2dda..1559b9a 100644
--- a/plugins/pychrysalide/format/symbol.c
+++ b/plugins/pychrysalide/format/symbol.c
@@ -215,6 +215,7 @@ static void py_binary_symbol_init_gclass(GBinSymbolClass *class, gpointer unused
static char *py_binary_symbol_get_label_wrapper(const GBinSymbol *symbol)
{
char *result; /* Etiquette à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *pyret; /* Bilan de consultation */
@@ -229,6 +230,8 @@ static char *py_binary_symbol_get_label_wrapper(const GBinSymbol *symbol)
result = NULL;
+ gstate = PyGILState_Ensure();
+
pyobj = pygobject_new(G_OBJECT(symbol));
if (has_python_method(pyobj, "_get_label"))
@@ -247,6 +250,8 @@ static char *py_binary_symbol_get_label_wrapper(const GBinSymbol *symbol)
Py_DECREF(pyobj);
+ PyGILState_Release(gstate);
+
return result;
}
diff --git a/plugins/pychrysalide/gui/item.c b/plugins/pychrysalide/gui/item.c
index 2046587..eb140fb 100644
--- a/plugins/pychrysalide/gui/item.c
+++ b/plugins/pychrysalide/gui/item.c
@@ -291,19 +291,16 @@ static GtkWidget *py_editor_item_get_widget_wrapper(const GEditorItem *item)
static void py_editor_item_change_content_wrapper(GEditorItem *item, GLoadedContent *old, GLoadedContent *new)
{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
- PyThreadState *tstate; /* Contexte d'environnement */
PyObject *pyold; /* Conversion ou None */
PyObject *pynew; /* Conversion ou None */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyret; /* Retour de Python */
- pyobj = pygobject_new(G_OBJECT(item));
-
- tstate = get_pychrysalide_main_tstate();
+ gstate = PyGILState_Ensure();
- if (tstate != NULL)
- PyEval_RestoreThread(tstate);
+ pyobj = pygobject_new(G_OBJECT(item));
if (has_python_method(pyobj, "_change_content"))
{
@@ -334,8 +331,7 @@ static void py_editor_item_change_content_wrapper(GEditorItem *item, GLoadedCont
}
- if (tstate != NULL)
- PyEval_SaveThread();
+ PyGILState_Release(gstate);
}
@@ -356,19 +352,16 @@ static void py_editor_item_change_content_wrapper(GEditorItem *item, GLoadedCont
static void py_editor_item_change_view_wrapper(GEditorItem *item, GLoadedPanel *old, GLoadedPanel *new)
{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
- PyThreadState *tstate; /* Contexte d'environnement */
PyObject *pyold; /* Conversion ou None */
PyObject *pynew; /* Conversion ou None */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyret; /* Retour de Python */
- pyobj = pygobject_new(G_OBJECT(item));
-
- tstate = get_pychrysalide_main_tstate();
+ gstate = PyGILState_Ensure();
- if (tstate != NULL)
- PyEval_RestoreThread(tstate);
+ pyobj = pygobject_new(G_OBJECT(item));
if (has_python_method(pyobj, "_change_view"))
{
@@ -399,8 +392,7 @@ static void py_editor_item_change_view_wrapper(GEditorItem *item, GLoadedPanel *
}
- if (tstate != NULL)
- PyEval_SaveThread();
+ PyGILState_Release(gstate);
}
@@ -420,17 +412,14 @@ static void py_editor_item_change_view_wrapper(GEditorItem *item, GLoadedPanel *
static void py_editor_item_update_view_wrapper(GEditorItem *item, GLoadedPanel *panel)
{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
- PyThreadState *tstate; /* Contexte d'environnement */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyret; /* Retour de Python */
- pyobj = pygobject_new(G_OBJECT(item));
-
- tstate = get_pychrysalide_main_tstate();
+ gstate = PyGILState_Ensure();
- if (tstate != NULL)
- PyEval_RestoreThread(tstate);
+ pyobj = pygobject_new(G_OBJECT(item));
if (has_python_method(pyobj, "_update_view"))
{
@@ -444,8 +433,7 @@ static void py_editor_item_update_view_wrapper(GEditorItem *item, GLoadedPanel *
}
- if (tstate != NULL)
- PyEval_SaveThread();
+ PyGILState_Release(gstate);
}
@@ -466,17 +454,14 @@ static void py_editor_item_update_view_wrapper(GEditorItem *item, GLoadedPanel *
static void py_editor_item_track_cursor_wrapper(GEditorItem *item, GLoadedPanel *panel, const GLineCursor *cursor)
{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
- PyThreadState *tstate; /* Contexte d'environnement */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyret; /* Retour de Python */
- pyobj = pygobject_new(G_OBJECT(item));
-
- tstate = get_pychrysalide_main_tstate();
+ gstate = PyGILState_Ensure();
- if (tstate != NULL)
- PyEval_RestoreThread(tstate);
+ pyobj = pygobject_new(G_OBJECT(item));
if (has_python_method(pyobj, "_track_cursor"))
{
@@ -491,8 +476,7 @@ static void py_editor_item_track_cursor_wrapper(GEditorItem *item, GLoadedPanel
}
- if (tstate != NULL)
- PyEval_SaveThread();
+ PyGILState_Release(gstate);
}
@@ -513,17 +497,14 @@ static void py_editor_item_track_cursor_wrapper(GEditorItem *item, GLoadedPanel
static void py_editor_item_focus_cursor_wrapper(GEditorItem *item, GLoadedContent *content, const GLineCursor *cursor)
{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
- PyThreadState *tstate; /* Contexte d'environnement */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyret; /* Retour de Python */
- pyobj = pygobject_new(G_OBJECT(item));
-
- tstate = get_pychrysalide_main_tstate();
+ gstate = PyGILState_Ensure();
- if (tstate != NULL)
- PyEval_RestoreThread(tstate);
+ pyobj = pygobject_new(G_OBJECT(item));
if (has_python_method(pyobj, "_focus_cursor"))
{
@@ -538,8 +519,7 @@ static void py_editor_item_focus_cursor_wrapper(GEditorItem *item, GLoadedConten
}
- if (tstate != NULL)
- PyEval_SaveThread();
+ PyGILState_Release(gstate);
}
diff --git a/plugins/pychrysalide/helpers.c b/plugins/pychrysalide/helpers.c
index 8e7c10c..e0a3340 100644
--- a/plugins/pychrysalide/helpers.c
+++ b/plugins/pychrysalide/helpers.c
@@ -234,6 +234,8 @@ PyObject *run_python_method(PyObject *module, const char *method, PyObject *args
PyObject *traceback; /* Pile d'appels de l'exception*/
PyObject *refmsg; /* Message de référence */
+ assert(PyGILState_Check() == 1);
+
/* Exécution */
result = NULL;