mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-16 21:35:25 +00:00
7059886: 6 JCK manual awt/Desktop tests fail with GTKLookAndFeel - GTK intialization issue
Reviewed-by: anthony, art
This commit is contained in:
parent
a2dc296d67
commit
88d5331a54
87
jdk/src/solaris/classes/sun/misc/GThreadHelper.java
Normal file
87
jdk/src/solaris/classes/sun/misc/GThreadHelper.java
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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 GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.misc;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* This class is used to prevent multiple calling of g_thread_init ()
|
||||
* and gdk_thread_init ().
|
||||
*
|
||||
* Since version 2.24 of GLib, calling g_thread_init () multiple times is
|
||||
* allowed, but it will crash for older versions. There are two ways to
|
||||
* find out if g_thread_init () has been called:
|
||||
* g_thread_get_initialized (), but it was introduced in 2.20
|
||||
* g_thread_supported (), but it is a macro and cannot be loaded with dlsym.
|
||||
*
|
||||
* usage:
|
||||
* <pre>
|
||||
* lock();
|
||||
* try {
|
||||
* if (!getAndSetInitializationNeededFlag()) {
|
||||
* //call to g_thread_init();
|
||||
* //call to gdk_thread_init();
|
||||
* }
|
||||
* } finally {
|
||||
* unlock();
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public final class GThreadHelper {
|
||||
|
||||
private static final ReentrantLock LOCK = new ReentrantLock();
|
||||
private static boolean isGThreadInitialized = false;
|
||||
|
||||
/**
|
||||
* Acquires the lock.
|
||||
*/
|
||||
public static void lock() {
|
||||
LOCK.lock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the lock.
|
||||
*/
|
||||
public static void unlock() {
|
||||
LOCK.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current value of initialization flag and sets it to {@code true}.
|
||||
* MUST be called under the lock.
|
||||
*
|
||||
* A return value of {@code false} indicates that the calling code
|
||||
* should call the g_thread_init() and gdk_thread_init() functions
|
||||
* before releasing the lock.
|
||||
*
|
||||
* @return {@code true} if initialization has been completed.
|
||||
*/
|
||||
public static boolean getAndSetInitializationNeededFlag() {
|
||||
boolean ret = isGThreadInitialized;
|
||||
isGThreadInitialized = true;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -67,7 +67,7 @@ JNIEXPORT jboolean JNICALL
|
||||
Java_sun_awt_UNIXToolkit_load_1gtk(JNIEnv *env, jclass klass)
|
||||
{
|
||||
#ifndef HEADLESS
|
||||
return (jboolean)gtk2_load();
|
||||
return (jboolean)gtk2_load(env);
|
||||
#else
|
||||
return JNI_FALSE;
|
||||
#endif /* !HEADLESS */
|
||||
|
||||
@ -81,7 +81,7 @@ const gint DEFAULT = 1 << 10;
|
||||
|
||||
static void *gtk2_libhandle = NULL;
|
||||
static void *gthread_libhandle = NULL;
|
||||
static gboolean flag_g_thread_get_initialized = FALSE;
|
||||
|
||||
static jmp_buf j;
|
||||
|
||||
/* Widgets */
|
||||
@ -502,7 +502,7 @@ void gtk2_file_chooser_load()
|
||||
fp_gtk_g_slist_length = dl_symbol("g_slist_length");
|
||||
}
|
||||
|
||||
gboolean gtk2_load()
|
||||
gboolean gtk2_load(JNIEnv *env)
|
||||
{
|
||||
gboolean result;
|
||||
int i;
|
||||
@ -533,6 +533,7 @@ gboolean gtk2_load()
|
||||
}
|
||||
|
||||
/* GLib */
|
||||
fp_glib_check_version = dl_symbol("glib_check_version");
|
||||
fp_g_free = dl_symbol("g_free");
|
||||
fp_g_object_unref = dl_symbol("g_object_unref");
|
||||
|
||||
@ -708,6 +709,9 @@ gboolean gtk2_load()
|
||||
/**
|
||||
* GLib thread system
|
||||
*/
|
||||
if (fp_glib_check_version(2, 20, 0) == NULL) {
|
||||
fp_g_thread_get_initialized = dl_symbol_gthread("g_thread_get_initialized");
|
||||
}
|
||||
fp_g_thread_init = dl_symbol_gthread("g_thread_init");
|
||||
fp_gdk_threads_init = dl_symbol("gdk_threads_init");
|
||||
fp_gdk_threads_enter = dl_symbol("gdk_threads_enter");
|
||||
@ -810,16 +814,33 @@ gboolean gtk2_load()
|
||||
io_handler = XSetIOErrorHandler(NULL);
|
||||
|
||||
if (fp_gtk_check_version(2, 2, 0) == NULL) {
|
||||
// Init the thread system to use GLib in a thread-safe mode
|
||||
if (!flag_g_thread_get_initialized) {
|
||||
flag_g_thread_get_initialized = TRUE;
|
||||
jclass clazz = (*env)->FindClass(env, "sun/misc/GThreadHelper");
|
||||
jmethodID mid_getAndSetInitializationNeededFlag =
|
||||
(*env)->GetStaticMethodID(env, clazz, "getAndSetInitializationNeededFlag", "()Z");
|
||||
jmethodID mid_lock = (*env)->GetStaticMethodID(env, clazz, "lock", "()V");
|
||||
jmethodID mid_unlock = (*env)->GetStaticMethodID(env, clazz, "unlock", "()V");
|
||||
|
||||
fp_g_thread_init(NULL);
|
||||
// Init the thread system to use GLib in a thread-safe mode
|
||||
(*env)->CallStaticVoidMethod(env, clazz, mid_lock);
|
||||
|
||||
// Calling g_thread_init() multiple times leads to crash on GLib < 2.24
|
||||
// We can use g_thread_get_initialized () but it is available only for
|
||||
// GLib >= 2.20. We rely on GThreadHelper for GLib < 2.20.
|
||||
gboolean is_g_thread_get_initialized = FALSE;
|
||||
if (fp_glib_check_version(2, 20, 0) == NULL) {
|
||||
is_g_thread_get_initialized = fp_g_thread_get_initialized();
|
||||
}
|
||||
|
||||
if (!(*env)->CallStaticBooleanMethod(env, clazz, mid_getAndSetInitializationNeededFlag)) {
|
||||
if (!is_g_thread_get_initialized) {
|
||||
fp_g_thread_init(NULL);
|
||||
}
|
||||
|
||||
//According the GTK documentation, gdk_threads_init() should be
|
||||
//called before gtk_init() or gtk_init_check()
|
||||
fp_gdk_threads_init();
|
||||
}
|
||||
(*env)->CallStaticVoidMethod(env, clazz, mid_unlock);
|
||||
}
|
||||
result = (*fp_gtk_init_check)(NULL, NULL);
|
||||
|
||||
|
||||
@ -643,6 +643,14 @@ typedef struct _GThreadFunctions GThreadFunctions;
|
||||
*/
|
||||
const char *getStrFor(JNIEnv *env, jstring value);
|
||||
|
||||
/**
|
||||
* Returns :
|
||||
* NULL if the GLib library is compatible with the given version, or a string
|
||||
* describing the version mismatch.
|
||||
*/
|
||||
gchar* (*fp_glib_check_version)(guint required_major, guint required_minor,
|
||||
guint required_micro);
|
||||
|
||||
/*
|
||||
* Check whether the gtk2 library is available and meets the minimum
|
||||
* version requirement. If the library is already loaded this method has no
|
||||
@ -663,7 +671,7 @@ gchar* (*fp_gtk_check_version)(guint required_major, guint required_minor,
|
||||
* effect and returns success.
|
||||
* Returns FALSE on failure and TRUE on success.
|
||||
*/
|
||||
gboolean gtk2_load();
|
||||
gboolean gtk2_load(JNIEnv *env);
|
||||
|
||||
/*
|
||||
* Loads fp_gtk_show_uri function pointer. This initialization is
|
||||
@ -801,6 +809,12 @@ void (*fp_gtk_main)(void);
|
||||
guint (*fp_gtk_main_level)(void);
|
||||
|
||||
|
||||
/**
|
||||
* This function is available for GLIB > 2.20, so it MUST be
|
||||
* called within (fp_glib_check_version(2, 20, 0) == NULL) check.
|
||||
*/
|
||||
gboolean (*fp_g_thread_get_initialized)(void);
|
||||
|
||||
void (*fp_g_thread_init)(GThreadFunctions *vtable);
|
||||
void (*fp_gdk_threads_init)(void);
|
||||
void (*fp_gdk_threads_enter)(void);
|
||||
|
||||
@ -42,7 +42,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XDesktopPeer_init
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
if (gtk2_load() && gtk2_show_uri_load()) {
|
||||
if (gtk2_load(env) && gtk2_show_uri_load()) {
|
||||
gtk_has_been_loaded = TRUE;
|
||||
return JNI_TRUE;
|
||||
} else if (gnome_load()) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user