gstreamer/gst/gstobject.override
Edward Hervey db76ff3908 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.
2007-01-11 17:45:46 +00:00

152 lines
4 KiB
C

/* -*- Mode: C -*- */
/* gst-python
* Copyright (C) 2005 Edward Hervey
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Edward Hervey <edward@fluendo.com>
*/
%%
ignore
gst_object_default_deep_notify
gst_object_check_uniqueness
gst_object_replace
%%
override-attr GstObject.__gstrefcount__
/* keep this attribute around even after 2.8 for compatibility reasons */
static PyObject *
_wrap_gst_object__get___gstrefcount__ (PyGObject * self, void *closure)
{
return PyInt_FromLong (GST_OBJECT_REFCOUNT_VALUE (self->obj));
}
%%
override-slot GstObject.tp_repr
static PyObject *
_wrap_gst_object_tp_repr (PyObject * self)
{
gchar *repr;
PyObject *ret;
GstObject *object = GST_OBJECT (pygobject_get (self));
repr = g_strdup_printf ("<%s object (%s) at 0x%lx>",
self->ob_type->tp_name,
GST_OBJECT_NAME (object) ? GST_OBJECT_NAME (object) : "unnamed",
(long) self);
ret = PyString_FromString (repr);
g_free (repr);
return ret;
}
%%
override-slot GstObject.tp_str
static PyObject *
_wrap_gst_object_tp_str (PyObject * self)
{
gchar *repr, *path;
PyObject *ret;
GstObject *object = GST_OBJECT (pygobject_get (self));
path = gst_object_get_path_string (object);
repr = g_strdup_printf ("%s (%s)", path, self->ob_type->tp_name);
ret = PyString_FromString (repr);
g_free (repr);
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", &param_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;
}