/* * java-gnome, a UI library for writing GTK and GNOME programs from Java! * * Copyright © 2007-2010 Operational Dynamics Consulting, Pty Ltd and Others * * The code in this file, and the program it is a part of, is made available * to you by its authors as open source software: you can redistribute it * and/or modify it under the terms of the GNU General Public License version * 2 ("GPL") as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GPL for more details. * * You should have received a copy of the GPL along with this program. If not, * see http://www.gnu.org/licenses/. The authors of this program may be * contacted through http://java-gnome.sourceforge.net/. * * Linking this library statically or dynamically with other modules is making * a combined work based on this library. Thus, the terms and conditions of * the GPL cover the whole combination. As a special exception (the * "Claspath Exception"), the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent modules, * and to copy and distribute the resulting executable under terms of your * choice, provided that you also meet, for each linked independent module, * the terms and conditions of the license of that module. An independent * module is a module which is not derived from or based on this library. If * you modify this library, you may extend the Classpath Exception to your * version of the library, but you are not obligated to do so. If you do not * wish to do so, delete this exception statement from your version. */ #include #include #include "bindings_java.h" /* * Permit multi threaded use of GTK by synchronizing access via "the GTK * main lock". We do this almost entirely on the Java side, except that a * mutex is a mutex, ultimately, so by overriding the default implementations * in gtk+'s gdk/gdk.c we can properly interoperate with the rest of the GTK * library. */ static jobject lock; /** * Save a reference to the lock object on the Java side, and then register our * custom lock functions. This function also initializes GLib's thread * mechanism; which call needs to be the _very_ first thing in a GLib program * these days. */ void bindings_java_threads_init ( JNIEnv *env, jobject obj ) { // must be first GLib call! g_thread_init(NULL); // now get about setting up GDK's threads lock = (*env)->NewGlobalRef(env, obj); gdk_threads_set_lock_functions(bindings_java_threads_lock, bindings_java_threads_unlock); gdk_threads_init(); } /** * Enter the monitor for our Java side GDK lock object. This is, strictly, * the opening half of a sychronized (obj) { ... } in Java, as expressed in * JNI. */ /* * Signature the prototype of the generic (*GCallback) prototype, meeting the * requirements of the first argument to gdk_threads_set_lock_functions() */ void bindings_java_threads_lock ( ) { JNIEnv* env; env = bindings_java_getEnv(); if ((*env)->MonitorEnter(env, lock) != JNI_OK) { g_critical("Error trying to get Java side GDK lock!?!"); } } /** * Release the monitor (lock) held on our Java side GDK lock object. Note the * Sun Java VM implementation will still show this thread as having entered * the lock, but if you look at a thread dump closely you'll see it waiting * on monitor, which is correct. */ /* * Signature the prototype of the generic (*GCallback) prototype, meeting the * requirements of the second argument to gdk_threads_set_lock_functions() */ void bindings_java_threads_unlock ( ) { JNIEnv* env; env = bindings_java_getEnv(); if ((*env)->MonitorExit(env, lock) != JNI_OK) { g_critical("Error trying to release Java side GDK lock?!?"); } }