[java-gnome-hackers] Dialog's run() blocking other threads
Brought to you by:
afcowie
From: Andrew C. <an...@op...> - 2010-01-13 00:51:15
|
Guillaume hit an interesting problem: Dialog's run() is preventing his other GTK-using threads from running. I talked about it with him on IRC, and he filed https://bugzilla.gnome.org/show_bug.cgi?id=606796 for us. The native gtk_dialog_run() is known to be magic. It has it's own pseudo gtk main loop in order to implement the modal dialog effect. Not to mention other voodoo-ness. http://library.gnome.org/devel/gtk/stable/GtkDialog.html#gtk-dialog-run We expect gtk_dialog_run() to release the GDK lock just like gtk_main() does. Reading the C code in GTK, it seems to be implemented the same. So, the problem is that our lock is nesting in the signal handler. That's fine, and to be expected. The reentrant lock we're using (a Java object monitor) means that the signal handler code can in turn keep making GTK calls and since it has the lock, they go through. But Dialog's run() could reasonably be expected to "release everything" and allow the rest of the code to run. So for that case [only] we need to be all the way out of the Gdk$Lock. That's not possible on the Java side [unless we replace the synchronized (lock) { ... } blocks with a java.util.concurrent.locks.Lock implementation of our own, along with the: lock.lock() try { ... } finally { lock.unlock() } pattern, to enable us to call unlock() elsewhere] However, be fore we get that ugly & invasive, we may be able to do a MonitorExit() / MonitorEnter() pair in C side GdkDialogOverride.gtk_dialog_run implementation. That's not necessarily a good idea. In fact, it's not really supposed to be allowed, but I think it'll work; in the end it's a direct wrapper around a VM instruction, and as far as I can tell it's just a counter in the monitor. We'll have to get our facts straight first. Guillaume said he'd run some tests over the weekend to verify that what we think happens actually happens [is still happening] with respect to gdk_threads_enter() and gdk_threads_leave() calls. As I noted on the bug (and Guillaume tested), there is a workaround for anyone having this problem: use present() on the Dialog and then connect() to Dialog.Response as necessary, letting the original main loop do it's thing and leave GtkDialog's magic inner main loop out of it. AfC Sydney -- Andrew Frederick Cowie Operational Dynamics is an operations and engineering consultancy focusing on IT strategy, organizational architecture, systems review, and effective procedures for change management: enabling successful deployment of mission critical information technology in enterprises, worldwide. http://www.operationaldynamics.com/ Sydney New York Toronto London |