[pygobject] Do not do any python calls when GObjects are destroyed after the python interpreter has been finaliz
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Do not do any python calls when GObjects are destroyed after the python interpreter has been finaliz
- Date: Mon, 25 Jun 2012 13:17:03 +0000 (UTC)
commit e92278692bb51679d6e957c2ac36db64498a7c73
Author: Simon Schampijer <simon schampijer de>
Date: Fri Jun 15 16:11:21 2012 +0200
Do not do any python calls when GObjects are destroyed after the python interpreter has been finalized
This happens when pygobject_data_free () function is called after the python
interpreter shuts down, we can't do python calls after that.
Benzea did the findings because of a bug in Sugar, and commented in this
SugarLabs ticket: http://bugs.sugarlabs.org/ticket/3670
https://bugzilla.gnome.org/show_bug.cgi?id=678046
Signed-off-by: Benjamin Berg <benzea sugarlabs org>
Signed-off-by: Martin Pitt <martinpitt gnome org>
gi/_gobject/pygobject.c | 27 ++++++++++++++++++++++-----
1 files changed, 22 insertions(+), 5 deletions(-)
---
diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c
index d9d2969..355c6d0 100644
--- a/gi/_gobject/pygobject.c
+++ b/gi/_gobject/pygobject.c
@@ -57,15 +57,28 @@ GQuark pygobject_instance_data_key;
void
pygobject_data_free(PyGObjectData *data)
{
- PyGILState_STATE state = pyglib_gil_state_ensure();
+ /* This function may be called after the python interpreter has already
+ * been shut down. If this happens, we cannot do any python calls, so just
+ * free the memory. */
+ PyGILState_STATE state;
+ PyThreadState *_save = NULL;
+
GSList *closures, *tmp;
- Py_DECREF(data->type);
+
+ if (Py_IsInitialized()) {
+ state = pyglib_gil_state_ensure();
+ Py_DECREF(data->type);
+ /* We cannot use pyg_begin_allow_threads here because this is inside
+ * a branch. */
+ if (pyg_threads_enabled)
+ _save = PyEval_SaveThread();
+ }
+
tmp = closures = data->closures;
#ifndef NDEBUG
data->closures = NULL;
data->type = NULL;
#endif
- pyg_begin_allow_threads;
while (tmp) {
GClosure *closure = tmp->data;
@@ -74,13 +87,17 @@ pygobject_data_free(PyGObjectData *data)
tmp = tmp->next;
g_closure_invalidate(closure);
}
- pyg_end_allow_threads;
if (data->closures != NULL)
g_warning("invalidated all closures, but data->closures != NULL !");
g_free(data);
- pyglib_gil_state_release(state);
+
+ if (Py_IsInitialized()) {
+ if (pyg_threads_enabled)
+ PyEval_RestoreThread(_save);
+ pyglib_gil_state_release(state);
+ }
}
static inline PyGObjectData *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]