Re: [pygtk] PyGTK deadlocks... I know, right?
Am 12.01.2013 10:24, schrieb Niklas Koep: 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. Here's a minimal example of an app that demonstrates the issue: http://pastebin.com/b4VTGy9q. Any ideas of an obvious issue I'm overlooking? I'd greatly appreciate any input. Cheers! Calling gtk.Dialog.run() starts a second mainloop, which in a non-threaded application will block the original mainloop until it exits. This is useful for modal dialogs, but this is not what you want here. I don't know in detail what is happening in your example, but my guess would be that calling gtk.Dialog.run() also blocks the glib.MainLoop driving gstreamer, causing havoc once it continues. Working example below. Cheers, Christian #!/usr/bin/env python2 """ $ python2 --version Python 2.7.3 $ pkg-config pygtk-2.0 --modversion 2.24.0 $ pkg-config --modversion gstreamer-0.10 0.10.36 """ import gst import gtk gtk.gdk.threads_init() import gobject gobject.threads_init() def main(): bin_ = gst.element_factory_make("playbin2") bus = bin_.get_bus() bus.add_signal_watch() bus.connect("message", on_message) window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.set_size_request(300, 180) window.connect("delete-event", quit, bin_) vbox = gtk.VBox() window.add(vbox) button = gtk.Button("play") button.connect("clicked", on_clicked, bin_) vbox.pack_start(button, False) button = gtk.Button("message") button.connect("clicked", on_message_clicked, bin_) vbox.pack_start(button, False) window.show_all() gtk.main() def quit(window, event, bin_): bin_.set_state(gst.STATE_NULL) gtk.main_quit() return False def on_message_clicked (button, bin_): err = gst.GError ("test", gst.CORE_ERROR_FAILED, "test") msg = gst.message_new_error (bin_, err, "test error handling") bin_.post_message (msg) def on_clicked(button, bin_): bin_.set_property("uri", "file:///tmp/test.mp3") bin_.set_state(gst.STATE_PLAYING) def on_message(bus, message): if message.type == gst.MESSAGE_ERROR: err, debug = message.parse_error() # FIXME: without the context manager destroying the dialog causes a #deadlock, but shouldn't this lock protection be redundant? #with gtk.gdk.lock: error_dialog("Error", "%s" % err) error_dialog("Error", "%s" % err) def on_response(diag, res): diag.destroy() def error_dialog(text, secondary_text=""): diag = gtk.MessageDialog( flags=gtk.DIALOG_DESTROY_WITH_PARENT|gtk.DIALOG_MODAL, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK ) diag.set_property("text", text) diag.set_property("secondary-text", secondary_text) diag.connect("response", on_response) diag.show() if __name__ == "__main__": main() ___ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://faq.pygtk.org/
Re: [pygtk] PyGTK deadlocks... I know, right?
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/
Re: [pygtk] PyGTK deadlocks... I know, right?
of course if you open a message dialog in a single threaded app you stop the application until the user presses on the ok button. if you want the app to go on you need a second non graphical thread. otherwise use the notifications: subprocess.call("notify-send CIAO, shell=True) On Sat, Jan 12, 2013 at 10: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. Here's a minimal example of an app that > demonstrates the issue: http://pastebin.com/b4VTGy9q. > > Any ideas of an obvious issue I'm overlooking? I'd greatly appreciate any > input. Cheers! > > ___ > pygtk mailing list pygtk@daa.com.au > http://www.daa.com.au/mailman/listinfo/pygtk > Read the PyGTK FAQ: http://faq.pygtk.org/ > ___ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://faq.pygtk.org/
[pygtk] PyGTK deadlocks... I know, right?
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. Here's a minimal example of an app that demonstrates the issue: http://pastebin.com/b4VTGy9q. Any ideas of an obvious issue I'm overlooking? I'd greatly appreciate any input. Cheers! ___ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://faq.pygtk.org/