summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Dahlin <johan@src.gnome.org>2004-08-03 14:11:46 +0000
committerJohan Dahlin <johan@src.gnome.org>2004-08-03 14:11:46 +0000
commit90aaf720cefcaed82196ea275b3a513315877300 (patch)
tree3097d16165d7b0d8268e768cab019a553f2214b6
parent3e41db376f6e40c2df01a1f83c2ecf10a5315084 (diff)
downloadpygobject-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.c47
-rw-r--r--gobject/pygboxed.c15
-rw-r--r--gobject/pygmaincontext.c4
-rw-r--r--gobject/pygmainloop.c4
-rw-r--r--gobject/pygobject.c31
-rw-r--r--gobject/pygpointer.c8
-rw-r--r--gobject/pygtype.c21
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(&params[0], G_OBJECT_TYPE(self->obj));
g_value_set_object(&params[0], G_OBJECT(self->obj));
@@ -1036,14 +1038,15 @@ pygobject_emit(PyGObject *self, PyObject *args)
if (pyg_value_from_pyobject(&params[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(&params[i+1])), i);
PyErr_SetString(PyExc_TypeError, buf);
+ Py_UNBLOCK_THREADS;
for (i = 0; i < query.n_params + 1; i++)
g_value_unset(&params[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(&params[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(&param_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);
}
/**