First, a disclaimer: I don't grok threads, so what I'm saying may be
wrong. If someone else says differently, believe them. But I think
I've figured out what's going on.
On 01/12/2013 06:24 AM, Niklas Koep wrote:
Here's one. I'm using PyGTK 2.24 with gstreamer 0.10.36. Whenever
gstreamer reports an error on my playbin2's message bus I display the
error in a gtk.MessageDialog. This causes the app to deadlock unless I
use a context manager with gtk.gdk.lock. At first I suspected a
threading issue, but according to the gstreamer docs messages on the bus
are emitted from the main thread so I don't see how threading could be
an issue. Nevertheless, I verified this by retrieving the thread ids
with libc via ctypes and they're identical.
I suspect your reasoning is faulty [1], but your conclusion is correct:
the signal handlers will be called in the main thread. But why would
you expect them to be called inside the GDK lock? The whole point of
calling threads_init, as I understand it, is to tell the main loop to
release the lock occasionally so that you can grab it in another thread.
So no matter what thread you're in, you need to grab the lock when you
need it. (And if you're doing anything GTKish, you need it.) The need
for the lock in your sample program makes sense.
But do you actually need a threaded pyGTK? GStreamer will use as many
threads as it deems necessary completely independently of whether you
set up threading in Python (I think). So you can also get your sample
program to work by taking out the two threads_init() calls as well as
the gtk.gdk.lock. Maybe your real program does need threads, but what
you've shown us certainly doesn't [2].
Hope that helps,
Robert
[1] I suspect you were looking here
(http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/chapter-bus.html),
where it says that bus handlers will be called from the main thread.
But you're not using those; you're using a GSignals-based approach. The
signal handlers will also be called from the main thread, which explains
your results.
[2] Note that you can also write a threaded Python program, but leave
the GTK part single-threaded. If you take out your
gtk.gdk.threads_init() call, you can also take out the gtk.gdk.lock.
You can use multiple threads in Python now, but you can only do GTK
stuff from the main thread. This isn't actually that much of a
restriction -- if you want to GTK stuff from a secondary thread, you
just put that code into gobject.idle_add(). It will then be executed in
the main thread (which always has the GDK lock in this approach) when
there's time. Personally, I find this way of thinking easier, but I try
to avoid threads completely if at all possible.
_______________________________________________
pygtk mailing list pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/