[pygtk] pygtk2 threading issues with gstreamer

David I. Lehn dlehn@vt.edu
Fri, 4 Oct 2002 15:17:49 -0400


Hi,

I'm working on Python the bindings for GStreamer http://gstreamer.net/.
gst-python module in CVS if you want to have a look.  Most of the API is
automagically wrapped up.  pygtk scripts work great! ;)

A bit of background: GStreamer sets up a graph of connected components
to process media.  The various components can live in containers that
run in their own threads.  Syncronization between threads is done with
async queues and data flow scheduling.

I'm having trouble figuring out how to handle threading issues.  Two
issues: lack of SMP performance and interpreter locking.

Initially I wanted to be able to write data processing elements in
Python.  This is partly done, I've got a trivial element written
already.  But I started to lose some hope of this having good
performance on SMP boxen when I learned all Python must be run in the
single interpreter thread. :(  Not really a app killer or anything just
unfortunate the full advantages of threads won't happen.  Can live with
this for now...

The more serious issue is how to deal with interpreter locking.  In a
script like the dvdplay.py example a multithreaded pipeline is setup.
This actually works just fine in the simple case of it all running in
the background behind pythons back via gstreamer functionality.

But there is a problem when callbacks from signals are used.  One easy
way to trigger this is to watch a "deep_notify" signal that is triggered
by sub-elements of the pipeline passing notifications up to their top
level container.

(This calling syntax used vs self.pipeline.connect() due to the current
unfortunate overloading of 'connect' to something else in one of the
gstreamer classes.  grrr.)

GObject.connect(self.pipeline,'deep_notify',somefunc)

This signal will get fired from multiple threads which causes the
interpreter to call somefunc multiple times without locking and get
crashes with messages like:

 SystemError: ../Objects/frameobject.c:235: bad argument to internal
 function

 GThread-ERROR **: file gthread-posix.c: line 226
 (g_cond_free_posix_impl): error 'Device or resource busy' during
 'pthread_cond_destroy ((pthread_cond_t *) cond)'

I'm not sure what the solution to this is.  I was thinking of a callback
wrapper in python or C.  But I'm not sure either of those would work
without some ugliness.  It looks like there is thread block/unblock code
in pygtype.c to handle this sort of thing but that's either not the
problem or it isn't working.

Any suggestions?

-dave