diff options
author | Johan Dahlin <johan@src.gnome.org> | 2004-08-03 14:11:46 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2004-08-03 14:11:46 +0000 |
commit | 90aaf720cefcaed82196ea275b3a513315877300 (patch) | |
tree | 3097d16165d7b0d8268e768cab019a553f2214b6 | |
parent | 3e41db376f6e40c2df01a1f83c2ecf10a5315084 (diff) | |
download | pygobject-90aaf720cefcaed82196ea275b3a513315877300.tar.gz pygobject-90aaf720cefcaed82196ea275b3a513315877300.tar.xz pygobject-90aaf720cefcaed82196ea275b3a513315877300.zip |
Clean up most functions here to have only one return path.
* gtk/pygtktreemodel.c: Clean up most functions here to have only
one return path.
* gobject/pygobject.c (pygobject_emit): Protect g_value_unset by
UNBLOCK/BLOCK_THREADS since it might call pygobject_free which
will result in a deadlock.
* gobject/gobjectmodule.c (pyg_thread_init): New function, move
thread initalization stuff in here.
* All over the place: Kill pyg_block/unblock_threads and use
PyGILState and Py_BEGIN/END_ALLOW_THREADS.
unblock [code] block calls are replaced by Py_BEGIN/END and
block [code] unblock calls are replaced by PyGILState.
-rw-r--r-- | gobject/gobjectmodule.c | 47 | ||||
-rw-r--r-- | gobject/pygboxed.c | 15 | ||||
-rw-r--r-- | gobject/pygmaincontext.c | 4 | ||||
-rw-r--r-- | gobject/pygmainloop.c | 4 | ||||
-rw-r--r-- | gobject/pygobject.c | 31 | ||||
-rw-r--r-- | gobject/pygpointer.c | 8 | ||||
-rw-r--r-- | gobject/pygtype.c | 21 |
7 files changed, 73 insertions, 57 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index 709ecd0..af6e31f 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -71,10 +71,11 @@ void pyg_destroy_notify(gpointer user_data) { PyObject *obj = (PyObject *)user_data; + PyGILState_STATE state; - pyg_block_threads(); + state = PyGILState_Ensure(); Py_DECREF(obj); - pyg_unblock_threads(); + PyGILState_Release(state); } @@ -95,10 +96,9 @@ static void pyobject_free(gpointer boxed) { PyObject *object = boxed; - - pyg_block_threads(); + PyGILState_STATE state = PyGILState_Ensure(); Py_DECREF(object); - pyg_unblock_threads(); + PyGILState_Release(state); } @@ -330,14 +330,13 @@ pyg_object_set_property (GObject *object, guint property_id, PyObject *py_pspec, *py_value; PyGILState_STATE state; - pyg_block_threads(); state = PyGILState_Ensure(); object_wrapper = pygobject_new(object); if (object_wrapper == NULL) { - pyg_unblock_threads(); - g_return_if_fail(object_wrapper != NULL); + PyGILState_Release(state); + return; } py_pspec = pyg_param_spec_new(pspec); @@ -356,7 +355,6 @@ pyg_object_set_property (GObject *object, guint property_id, Py_DECREF(py_value); PyGILState_Release(state); - pyg_unblock_threads(); } static void @@ -367,14 +365,13 @@ pyg_object_get_property (GObject *object, guint property_id, PyObject *py_pspec; PyGILState_STATE state; - pyg_block_threads(); state = PyGILState_Ensure(); object_wrapper = pygobject_new(object); if (object_wrapper == NULL) { - pyg_unblock_threads(); - g_return_if_fail(object_wrapper != NULL); + PyGILState_Release(state); + return; } py_pspec = pyg_param_spec_new(pspec); @@ -388,7 +385,6 @@ pyg_object_get_property (GObject *object, guint property_id, Py_XDECREF(retval); PyGILState_Release(state); - pyg_unblock_threads(); } static void @@ -1259,7 +1255,6 @@ handler_marshal(gpointer user_data) g_return_val_if_fail(user_data != NULL, FALSE); - pyg_block_threads(); state = PyGILState_Ensure(); tuple = (PyObject *)user_data; @@ -1274,7 +1269,6 @@ handler_marshal(gpointer user_data) } PyGILState_Release(state); - pyg_unblock_threads(); return res; } @@ -1364,7 +1358,6 @@ iowatch_marshal(GIOChannel *source, GIOCondition condition, gpointer user_data) g_return_val_if_fail(user_data != NULL, FALSE); - pyg_block_threads(); state = PyGILState_Ensure(); tuple = (PyObject *)user_data; @@ -1386,7 +1379,6 @@ iowatch_marshal(GIOChannel *source, GIOCondition condition, gpointer user_data) } PyGILState_Release(state); - pyg_unblock_threads(); return res; } @@ -1467,6 +1459,23 @@ pyg_main_context_default (PyObject *unused) } +static PyObject * +pyg_thread_init (PyObject *unused) +{ + /* FIXME: Should we raise an exception if we don't + have threading enabled. This will make + the import/initialize code quite ugly */ +#ifdef ENABLE_PYGTK_THREADING + g_print ("calling InitThreads\n"); + PyEval_InitThreads(); + if (!g_threads_got_initialized) + g_thread_init(NULL); +#endif + + Py_INCREF(Py_None); + return Py_None; +} + static PyMethodDef pygobject_functions[] = { { "type_name", pyg_type_name, METH_VARARGS }, { "type_from_name", pyg_type_from_name, METH_VARARGS }, @@ -1484,6 +1493,7 @@ static PyMethodDef pygobject_functions[] = { { "io_add_watch", (PyCFunction)pyg_io_add_watch, METH_VARARGS|METH_KEYWORDS }, { "source_remove", pyg_source_remove, METH_VARARGS }, { "main_context_default", (PyCFunction)pyg_main_context_default, METH_NOARGS }, + { "thread_init", (PyCFunction)pyg_thread_init, METH_NOARGS }, { NULL, NULL, 0 } }; @@ -1620,7 +1630,6 @@ pyg_error_check(GError **error) PyObject *exc_instance; PyObject *d; - pyg_block_threads(); state = PyGILState_Ensure(); exc_instance = PyObject_CallFunction(gerror_exc, "z", @@ -1644,7 +1653,6 @@ pyg_error_check(GError **error) g_clear_error(error); PyGILState_Release(state); - pyg_unblock_threads(); return TRUE; } @@ -1826,7 +1834,6 @@ initgobject(void) d = PyModule_GetDict(m); #ifdef ENABLE_PYGTK_THREADING - PyEval_InitThreads(); if (!g_threads_got_initialized) g_thread_init(NULL); #endif diff --git a/gobject/pygboxed.c b/gobject/pygboxed.c index 39f3d1c..05b2c13 100644 --- a/gobject/pygboxed.c +++ b/gobject/pygboxed.c @@ -30,9 +30,9 @@ static void pyg_boxed_dealloc(PyGBoxed *self) { if (self->free_on_dealloc && self->boxed) { - pyg_unblock_threads(); + PyGILState_STATE state = PyGILState_Ensure(); g_boxed_free(self->gtype, self->boxed); - pyg_block_threads(); + PyGILState_Release(state); } self->ob_type->tp_free((PyObject *)self); @@ -210,17 +210,18 @@ PyObject * pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed, gboolean own_ref) { + PyGILState_STATE state; PyGBoxed *self; PyTypeObject *tp; g_return_val_if_fail(boxed_type != 0, NULL); g_return_val_if_fail(!copy_boxed || (copy_boxed && own_ref), NULL); - pyg_block_threads(); + state = PyGILState_Ensure(); if (!boxed) { Py_INCREF(Py_None); - pyg_unblock_threads(); + PyGILState_Release(state); return Py_None; } @@ -230,7 +231,7 @@ pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed, self = PyObject_NEW(PyGBoxed, tp); if (self == NULL) { - pyg_unblock_threads(); + PyGILState_Release(state); return NULL; } @@ -240,8 +241,8 @@ pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed, self->gtype = boxed_type; self->free_on_dealloc = own_ref; - pyg_unblock_threads(); - + PyGILState_Release(state); + return (PyObject *)self; } diff --git a/gobject/pygmaincontext.c b/gobject/pygmaincontext.c index 7f8fdab..ee803c8 100644 --- a/gobject/pygmaincontext.c +++ b/gobject/pygmaincontext.c @@ -51,10 +51,10 @@ _wrap_g_main_context_iteration (PyGMainContext *self, PyObject *args) &may_block)) return NULL; - pyg_unblock_threads(); + Py_BEGIN_ALLOW_THREADS; py_ret = g_main_context_iteration(self->context, may_block) ? Py_True : Py_False; - pyg_block_threads(); + Py_END_ALLOW_THREADS; Py_INCREF(py_ret); return py_ret; diff --git a/gobject/pygmainloop.c b/gobject/pygmainloop.c index e0424cb..1a7e163 100644 --- a/gobject/pygmainloop.c +++ b/gobject/pygmainloop.c @@ -105,9 +105,9 @@ _wrap_g_main_loop_quit (PyGMainLoop *self) static PyObject * _wrap_g_main_loop_run (PyGMainLoop *self) { - pyg_unblock_threads(); + Py_BEGIN_ALLOW_THREADS; g_main_loop_run(self->loop); - pyg_block_threads(); + Py_END_ALLOW_THREADS; Py_INCREF(Py_None); return Py_None; diff --git a/gobject/pygobject.c b/gobject/pygobject.c index d29d1d7..b8073cf 100644 --- a/gobject/pygobject.c +++ b/gobject/pygobject.c @@ -364,9 +364,9 @@ pygobject_new(GObject *obj) self = PyObject_GC_New(PyGObject, tp); if (self == NULL) return NULL; - pyg_unblock_threads(); + Py_BEGIN_ALLOW_THREADS; self->obj = g_object_ref(obj); - pyg_block_threads(); + Py_END_ALLOW_THREADS; sink_object(self->obj); self->inst_dict = NULL; @@ -430,9 +430,9 @@ pygobject_dealloc(PyGObject *self) PyObject_GC_UnTrack((PyObject *)self); if (self->obj) { - pyg_unblock_threads(); + Py_BEGIN_ALLOW_THREADS; g_object_unref(self->obj); - pyg_block_threads(); + Py_END_ALLOW_THREADS; } self->obj = NULL; @@ -441,7 +441,7 @@ pygobject_dealloc(PyGObject *self) } self->inst_dict = NULL; - pyg_unblock_threads(); + Py_BEGIN_ALLOW_THREADS; tmp = self->closures; while (tmp) { GClosure *closure = tmp->data; @@ -452,7 +452,7 @@ pygobject_dealloc(PyGObject *self) g_closure_invalidate(closure); } self->closures = NULL; - pyg_block_threads(); + Py_END_ALLOW_THREADS; /* the following causes problems with subclassed types */ /* self->ob_type->tp_free((PyObject *)self); */ @@ -525,7 +525,7 @@ pygobject_clear(PyGObject *self) } self->inst_dict = NULL; - pyg_unblock_threads(); + Py_BEGIN_ALLOW_THREADS; tmp = self->closures; while (tmp) { GClosure *closure = tmp->data; @@ -535,15 +535,15 @@ pygobject_clear(PyGObject *self) tmp = tmp->next; g_closure_invalidate(closure); } - pyg_block_threads(); + Py_END_ALLOW_THREADS; if (self->closures != NULL) g_message("invalidated all closures, but self->closures != NULL !"); if (self->obj) { - pyg_unblock_threads(); + Py_BEGIN_ALLOW_THREADS; g_object_unref(self->obj); - pyg_block_threads(); + Py_END_ALLOW_THREADS; } self->obj = NULL; @@ -997,7 +997,8 @@ pygobject_emit(PyGObject *self, PyObject *args) gchar *name; GSignalQuery query; GValue *params, ret = { 0, }; - + PyThreadState *_save; + len = PyTuple_Size(args); if (len < 1) { PyErr_SetString(PyExc_TypeError,"GObject.emit needs at least one arg"); @@ -1024,6 +1025,7 @@ pygobject_emit(PyGObject *self, PyObject *args) PyErr_SetString(PyExc_TypeError, buf); return NULL; } + params = g_new0(GValue, query.n_params + 1); g_value_init(¶ms[0], G_OBJECT_TYPE(self->obj)); g_value_set_object(¶ms[0], G_OBJECT(self->obj)); @@ -1036,14 +1038,15 @@ pygobject_emit(PyGObject *self, PyObject *args) if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) { gchar buf[128]; - g_snprintf(buf, sizeof(buf), "could not convert type %s to %s required for parameter %d", item->ob_type->tp_name, g_type_name(G_VALUE_TYPE(¶ms[i+1])), i); PyErr_SetString(PyExc_TypeError, buf); + Py_UNBLOCK_THREADS; for (i = 0; i < query.n_params + 1; i++) g_value_unset(¶ms[i]); + Py_BLOCK_THREADS; g_free(params); return NULL; } @@ -1052,8 +1055,10 @@ pygobject_emit(PyGObject *self, PyObject *args) g_value_init(&ret, query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); g_signal_emitv(params, signal_id, detail, &ret); + Py_UNBLOCK_THREADS; for (i = 0; i < query.n_params + 1; i++) g_value_unset(¶ms[i]); + g_free(params); if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) { py_ret = pyg_value_as_pyobject(&ret, TRUE); @@ -1062,6 +1067,8 @@ pygobject_emit(PyGObject *self, PyObject *args) Py_INCREF(Py_None); py_ret = Py_None; } + Py_BLOCK_THREADS; + return py_ret; } diff --git a/gobject/pygpointer.c b/gobject/pygpointer.c index b7e3cfc..4173e7c 100644 --- a/gobject/pygpointer.c +++ b/gobject/pygpointer.c @@ -185,16 +185,16 @@ pyg_register_pointer(PyObject *dict, const gchar *class_name, PyObject * pyg_pointer_new(GType pointer_type, gpointer pointer) { + PyGILState_STATE state; PyGPointer *self; PyTypeObject *tp; - g_return_val_if_fail(pointer_type != 0, NULL); - pyg_block_threads(); + state = PyGILState_Ensure(); if (!pointer) { Py_INCREF(Py_None); - pyg_unblock_threads(); + PyGILState_Release(state); return Py_None; } @@ -203,7 +203,7 @@ pyg_pointer_new(GType pointer_type, gpointer pointer) tp = (PyTypeObject *)&PyGPointer_Type; /* fallback */ self = PyObject_NEW(PyGPointer, tp); - pyg_unblock_threads(); + PyGILState_Release(state); if (self == NULL) return NULL; diff --git a/gobject/pygtype.c b/gobject/pygtype.c index e6b97ff..404370c 100644 --- a/gobject/pygtype.c +++ b/gobject/pygtype.c @@ -723,15 +723,17 @@ static void pyg_closure_invalidate(gpointer data, GClosure *closure) { PyGClosure *pc = (PyGClosure *)closure; + PyGILState_STATE state; - pyg_block_threads(); + state = PyGILState_Ensure(); Py_XDECREF(pc->callback); Py_XDECREF(pc->extra_args); Py_XDECREF(pc->swap_data); + PyGILState_Release(state); + pc->callback = NULL; pc->extra_args = NULL; pc->swap_data = NULL; - pyg_unblock_threads(); } static void @@ -747,7 +749,6 @@ pyg_closure_marshal(GClosure *closure, PyObject *params, *ret; guint i; - pyg_block_threads(); state = PyGILState_Ensure(); /* construct Python tuple for the parameter values */ @@ -787,7 +788,6 @@ pyg_closure_marshal(GClosure *closure, Py_DECREF(params); PyGILState_Release(state); - pyg_unblock_threads(); } /** @@ -849,6 +849,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, gpointer invocation_hint, gpointer marshal_data) { + PyGILState_STATE state; GObject *object; PyObject *object_wrapper; GSignalInvocationHint *hint = (GSignalInvocationHint *)invocation_hint; @@ -857,9 +858,9 @@ pyg_signal_class_closure_marshal(GClosure *closure, PyObject *params, *ret; guint i, len; + state = PyGILState_Ensure(); + g_return_if_fail(invocation_hint != NULL); - - pyg_block_threads(); /* get the object passed as the first argument to the closure */ object = g_value_get_object(¶m_values[0]); g_return_if_fail(object != NULL && G_IS_OBJECT(object)); @@ -883,7 +884,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, if (!method) { PyErr_Clear(); Py_DECREF(object_wrapper); - pyg_unblock_threads(); + PyGILState_Release(state); return; } Py_DECREF(object_wrapper); @@ -897,7 +898,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, /* error condition */ if (!item) { Py_DECREF(params); - pyg_unblock_threads(); + PyGILState_Release(state); return; } PyTuple_SetItem(params, i - 1, item); @@ -924,7 +925,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, PyErr_Print(); Py_DECREF(method); Py_DECREF(params); - pyg_unblock_threads(); + PyGILState_Release(state); return; } Py_DECREF(method); @@ -932,7 +933,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, if (return_value) pyg_value_from_pyobject(return_value, ret); Py_DECREF(ret); - pyg_unblock_threads(); + PyGILState_Release(state); } /** |