From a0bb8ce2e7318ef40cb572ae6e2dca09c7ace8ae Mon Sep 17 00:00:00 2001
From: Simon Schampijer <simon@schampijer.de>
Date: Fri, 15 Jun 2012 16:11:21 +0200
Subject: [PATCH] Do not do any python calls when GObjects are destroyed after
the python interpreter has been finalized, #678046
More info: http://bugs.sugarlabs.org/ticket/3670
Signed-off: Benjamin Berg <benzea@sugarlabs.org>
---
gi/_gobject/pygobject.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c
index 75c8ba3..f0ff023 100644
a
|
b
|
GQuark pygobject_instance_data_key; |
57 | 57 | void |
58 | 58 | pygobject_data_free(PyGObjectData *data) |
59 | 59 | { |
60 | | PyGILState_STATE state = pyglib_gil_state_ensure(); |
| 60 | /* This function may be called after the python interpreter has already |
| 61 | * been shut down. If this happens, we cannot do any python calls, so just |
| 62 | * free the memory. */ |
| 63 | PyGILState_STATE state; |
| 64 | PyThreadState *_save = NULL; |
| 65 | |
61 | 66 | GSList *closures, *tmp; |
62 | | Py_DECREF(data->type); |
| 67 | |
| 68 | if (Py_IsInitialized()) { |
| 69 | state = pyglib_gil_state_ensure(); |
| 70 | Py_DECREF(data->type); |
| 71 | /* We cannot use pyg_begin_allow_threads here because this is inside |
| 72 | * a branch. */ |
| 73 | if (pyg_threads_enabled) |
| 74 | _save = PyEval_SaveThread(); |
| 75 | } |
| 76 | |
63 | 77 | tmp = closures = data->closures; |
64 | 78 | #ifndef NDEBUG |
65 | 79 | data->closures = NULL; |
66 | 80 | data->type = NULL; |
67 | 81 | #endif |
68 | | pyg_begin_allow_threads; |
69 | 82 | while (tmp) { |
70 | 83 | GClosure *closure = tmp->data; |
71 | 84 | |
… |
… |
pygobject_data_free(PyGObjectData *data) |
74 | 87 | tmp = tmp->next; |
75 | 88 | g_closure_invalidate(closure); |
76 | 89 | } |
77 | | pyg_end_allow_threads; |
78 | 90 | |
79 | 91 | if (data->closures != NULL) |
80 | 92 | g_warning("invalidated all closures, but data->closures != NULL !"); |
81 | 93 | |
82 | 94 | g_free(data); |
83 | | pyglib_gil_state_release(state); |
| 95 | |
| 96 | if (Py_IsInitialized()) { |
| 97 | if (pyg_threads_enabled) |
| 98 | PyEval_RestoreThread(_save); |
| 99 | pyglib_gil_state_release(state); |
| 100 | } |
84 | 101 | } |
85 | 102 | |
86 | 103 | static inline PyGObjectData * |