From db76ff39086acf74b698839bf8c297817da69e3e Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Thu, 11 Jan 2007 17:45:46 +0000 Subject: [PATCH] gst/gst.defs: Add declaration of gst_object_set_property so we can use our MT-safe version of set_property(). Original commit message from CVS: * gst/gst.defs: Add declaration of gst_object_set_property so we can use our MT-safe version of set_property(). * gst/gstobject.override: Implement a MT-safe version of g_object_set_property for GstObject. The problem is that currently g_object_set_property is called in pygobject with the GIL lock taken. This can cause deadlocks. Remove this hack once bug #395048 is fixed in pygobject and we depend on the fixed version. Thanks to Lord Wingo of the "realm.py haters club" for proposing the idea. --- ChangeLog | 14 +++++++++ gst/gst.defs | 6 ++++ gst/gstobject.override | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/ChangeLog b/ChangeLog index ebc72b1..f3ed047 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2007-01-11 Edward Hervey + + * gst/gst.defs: + Add declaration of gst_object_set_property so we can use our MT-safe + version of set_property(). + * gst/gstobject.override: + Implement a MT-safe version of g_object_set_property for GstObject. + The problem is that currently g_object_set_property is called in + pygobject with the GIL lock taken. This can cause deadlocks. + Remove this hack once bug #395048 is fixed in pygobject and we depend on + the fixed version. + Thanks to Lord Wingo of the "realm.py haters club" for proposing the + idea. + 2007-01-10 Edward Hervey * codegen/codegen.py: diff --git a/gst/gst.defs b/gst/gst.defs index 63e55c7..b9d9dc6 100644 --- a/gst/gst.defs +++ b/gst/gst.defs @@ -3269,6 +3269,12 @@ (return-type "none") ) +(define-method set_property + (of-object "GstObject") + (c-name "gst_object_set_property") + (return-type "none") +) + (define-function object_default_deep_notify (c-name "gst_object_default_deep_notify") (return-type "none") diff --git a/gst/gstobject.override b/gst/gstobject.override index d0d1875..ed2d45d 100644 --- a/gst/gstobject.override +++ b/gst/gstobject.override @@ -70,3 +70,83 @@ _wrap_gst_object_tp_str (PyObject * self) g_free (path); return ret; } +%% +override gst_object_set_property args + +/* + * REMOVE THE FOLLOWING CODE, once pygobject has fixed the issue of not + * releasing the GIL when calling g_object_set_property. + * + * See bug #395048 : set_property() doesn't release the GIL + **/ + +static gboolean +set_property_from_pspec(GObject *obj, + char *attr_name, + GParamSpec *pspec, + PyObject *pvalue) +{ + GValue value = { 0, }; + + if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) { + PyErr_Format(PyExc_TypeError, + "property '%s' can only be set in constructor", + attr_name); + return FALSE; + } + + if (!(pspec->flags & G_PARAM_WRITABLE)) { + PyErr_Format(PyExc_TypeError, + "property '%s' is not writable", attr_name); + return FALSE; + } + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + if (pyg_param_gvalue_from_pyobject(&value, pvalue, pspec) < 0) { + PyErr_SetString(PyExc_TypeError, + "could not convert argument to correct param type"); + return FALSE; + } + + pyg_begin_allow_threads; + g_object_set_property(obj, attr_name, &value); + pyg_end_allow_threads; + + g_value_unset(&value); + + return TRUE; +} + +static PyObject * +_wrap_gst_object_set_property(PyGObject *self, PyObject *args) +{ + gchar *param_name; + GParamSpec *pspec; + PyObject *pvalue; + + if (!PyArg_ParseTuple(args, "sO:gst.Object.set_property", ¶m_name, + &pvalue)) + return NULL; + + if (!GST_IS_OBJECT (self->obj)) { + PyErr_Format (PyExc_TypeError, + "object at %p of type %s is not initialized", + self, self->ob_type->tp_name); + return NULL; + } + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj), + param_name); + if (!pspec) { + PyErr_Format(PyExc_TypeError, + "object of type `%s' does not have property `%s'", + g_type_name(G_OBJECT_TYPE(self->obj)), param_name); + return NULL; + } + + if (!set_property_from_pspec(self->obj, param_name, pspec, pvalue)) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} -- 2.7.4