Hi,
There is at least one JNI call that is designed not to return. This is
that gtkMain native method in gnu.java.awt.peer.gtk.GtkToolkit. Some VMs
require all Java threads to run upto a garbage collection barrier before
garbage collection can be performed. If a Java thread never leaves JNI
code then this will never happen and the VM deadlocks. A solution to
this is to rewrite the gtkMain loop to something like what follows:
in GtkTookit.java:
public static void gtkMain() {
try {
while(true) {
while(gtkEventsPending()) {
gtkMainIteration();
}
Thread.sleep(10);
}
}
catch(InterruptedException e){}
}
public static native void gtkMainIteration();
private static native boolean gtkEventsPending();
in gnu_java_awt_peer_gtk_GtkToolkit.c (NB regenerate the JNI header files):
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkMainIteration
(JNIEnv *env __attribute__((unused)), jclass obj __attribute__((unused)))
{
gdk_threads_enter ();
gtk_main_iteration ();
gdk_threads_leave ();
}
JNIEXPORT jboolean JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkEventsPending
(JNIEnv *env __attribute__((unused)), jclass obj __attribute__((unused)))
{
gboolean pending;
gdk_threads_enter ();
pending = gtk_events_pending ();
gdk_threads_leave ();
return pending == TRUE ? JNI_TRUE : JNI_FALSE;
}
For performance the nested while loop could be moved into the JNI code.
Is having all JNI code return an option for classpath?
Thanks,
Ian Rogers