diff options
author | Sven Gothel <[email protected]> | 2011-06-26 06:43:46 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-06-26 06:43:46 +0200 |
commit | 56e46acce6d26e0fdc2fd317649b11f1f71f621a (patch) | |
tree | bc1d7714f0450681d584b2fafb123d47bab1b340 | |
parent | f405ae4ac0928fa5682f0a1f75c70cdb46e261b4 (diff) |
Woraround for bug 502: X11/NEWT Stalling due to libX11/XCB Multithreading bug (libX11 1.4.2, libXCB 1.7; ubuntu 11.04, ..)
- https://jogamp.org/bugzilla/show_bug.cgi?id=502
- set the boolean property 'nativewindow.x11.mt-bug' to 'true',
indicating the erroneous libX11/libXCB behavior. This will enable extensive X11 locking even in NEWT.
4 files changed, 46 insertions, 43 deletions
diff --git a/make/config/nativewindow/win32-CustomJavaCode.java b/make/config/nativewindow/win32-CustomJavaCode.java index 5d0c82998..e14e4d14c 100644 --- a/make/config/nativewindow/win32-CustomJavaCode.java +++ b/make/config/nativewindow/win32-CustomJavaCode.java @@ -25,6 +25,8 @@ } } + public static boolean requiresToolkitLock() { return false; } + private static RegisteredClass dummyWindowClass = null; private static Object dummyWindowSync = new Object(); diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index 51f4568c8..64781e418 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -91,6 +91,7 @@ public abstract class NativeWindowFactory { private static Class x11ToolkitLockClass; private static Constructor x11ToolkitLockConstructor; private static boolean isFirstUIActionOnProcess; + private static boolean requiresToolkitLock; /** Creates a new NativeWindowFactory instance. End users do not need to call this method. */ @@ -124,6 +125,8 @@ public abstract class NativeWindowFactory { static boolean initialized = false; private static void initNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) { + isFirstUIActionOnProcess = firstUIActionOnProcess; + String clazzName = null; if( TYPE_X11.equals(nativeWindowingTypePure) ) { clazzName = X11UtilClassName; @@ -134,6 +137,11 @@ public abstract class NativeWindowFactory { ReflectionUtil.callStaticMethod(clazzName, "initSingleton", new Class[] { boolean.class }, new Object[] { new Boolean(firstUIActionOnProcess) }, cl ); + + final Boolean res = (Boolean) ReflectionUtil.callStaticMethod(clazzName, "requiresToolkitLock", null, null, cl); + requiresToolkitLock = res.booleanValue(); + } else { + requiresToolkitLock = false; } } @@ -176,9 +184,8 @@ public abstract class NativeWindowFactory { if(firstUIActionOnProcess) { // X11 initialization before possible AWT initialization - initNativeImpl(firstUIActionOnProcess, cl); + initNativeImpl(true, cl); } - isFirstUIActionOnProcess = firstUIActionOnProcess; isAWTAvailable = false; // may be set to true below if( !Debug.getBooleanProperty("java.awt.headless", true, acc) && @@ -212,7 +219,7 @@ public abstract class NativeWindowFactory { } if(!firstUIActionOnProcess) { // X11 initialization after possible AWT initialization - initNativeImpl(firstUIActionOnProcess, cl); + initNativeImpl(false, cl); } registeredFactories = Collections.synchronizedMap(new HashMap()); @@ -239,6 +246,7 @@ public abstract class NativeWindowFactory { if(DEBUG) { System.err.println("NativeWindowFactory firstUIActionOnProcess "+firstUIActionOnProcess); + System.err.println("NativeWindowFactory requiresToolkitLock "+requiresToolkitLock); System.err.println("NativeWindowFactory isAWTAvailable "+isAWTAvailable+", defaultFactory "+factory); } } @@ -250,6 +258,11 @@ public abstract class NativeWindowFactory { return isFirstUIActionOnProcess; } + /** @return true if the underlying toolkit requires locking, otherwise false. */ + public static boolean requiresToolkitLock() { + return requiresToolkitLock; + } + /** @return true if not headless, AWT Component and NativeWindow's AWT part available */ public static boolean isAWTAvailable() { return isAWTAvailable; } @@ -318,7 +331,7 @@ public abstract class NativeWindowFactory { * </ul> */ public static ToolkitLock getDefaultToolkitLock(String type) { - if( !isFirstUIActionOnProcess() ) { + if( requiresToolkitLock() ) { if( TYPE_X11 == type || TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) ) { if( isAWTAvailable() ) { return getAWTToolkitLock(); @@ -364,7 +377,7 @@ public abstract class NativeWindowFactory { * </ul> */ public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) { - if( !isFirstUIActionOnProcess() ) { + if( requiresToolkitLock() ) { if( TYPE_X11 == type ) { if( 0== deviceHandle ) { throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11"); @@ -378,32 +391,6 @@ public abstract class NativeWindowFactory { return NativeWindowFactoryImpl.getNullToolkitLock(); } - /** - * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>. - * <br> - * <ul> - * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li> - * <ul> - * <li>If <b>X11 type</b> </li> - * <ul> - * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li> - * </ul> - * </ul> - * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li> - * </ul> - */ - public static ToolkitLock createDefaultToolkitLockNoAWT(String type, long deviceHandle) { - if( !isFirstUIActionOnProcess() ) { - if( TYPE_X11 == type ) { - if( 0== deviceHandle ) { - throw new RuntimeException("JAWTUtil.createDefaultToolkitLockNoAWT() called with NULL device but on X11"); - } - return createX11ToolkitLock(deviceHandle); - } - } - return NativeWindowFactoryImpl.getNullToolkitLock(); - } - protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) { try { return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)}); diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java index 8a6869d91..117184a71 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -51,19 +51,29 @@ import javax.media.nativewindow.util.Point; * Contains a thread safe X11 utility to retrieve display connections. */ public class X11Util { + /** + * 2011/06/14 libX11 1.4.2 and libxcb 1.7 bug 20708 - Multithreading Issues w/ OpenGL, .. + * https://bugs.freedesktop.org/show_bug.cgi?id=20708 + * https://jogamp.org/bugzilla/show_bug.cgi?id=502 + * Affects: Ubuntu 11.04, OpenSuSE 11, .. + * If the property <b>nativewindow.x11.mt-bug</b> is set to true, extensive X11 locking + * is being applied, avoiding X11 multithreading capabilities. + */ + public static final boolean MULTITHREADING_BUG = Debug.getBooleanProperty("nativewindow.x11.mt-bug", true, AccessController.getContext()); + public static final boolean XINITTHREADS_ALWAYS_ENABLED = true; + private static final boolean DEBUG = Debug.debug("X11Util"); private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.getBooleanProperty("nativewindow.debug.X11Util.TraceDisplayLifecycle", true, AccessController.getContext()); private static volatile String nullDisplayName = null; - private static boolean isFirstX11ActionOnProcess = false; + private static boolean requiresX11Lock = false; private static boolean isInit = false; private static int setX11ErrorHandlerRecCount = 0; private static Object setX11ErrorHandlerLock = new Object(); - public static final boolean XINITTHREADS_ALWAYS_ENABLED = true; - public static synchronized void initSingleton(boolean firstX11ActionOnProcess) { + public static synchronized void initSingleton(final boolean firstX11ActionOnProcess) { if(!isInit) { NWJNILibLoader.loadNativeWindow("x11"); @@ -73,10 +83,14 @@ public class X11Util { * ie NEWT (jogamp.newt.x11.X11Display.createNativeImpl()) !! */ initialize0( XINITTHREADS_ALWAYS_ENABLED ? true : firstX11ActionOnProcess ); - isFirstX11ActionOnProcess = firstX11ActionOnProcess; + requiresX11Lock = !firstX11ActionOnProcess || MULTITHREADING_BUG; + if(DEBUG) { - System.out.println("X11Util.isFirstX11ActionOnProcess: "+isFirstX11ActionOnProcess); + System.out.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+ + ", XINITTHREADS_ALWAYS_ENABLED "+XINITTHREADS_ALWAYS_ENABLED+ + ", MULTITHREADING_BUG "+MULTITHREADING_BUG+ + ", requiresX11Lock "+requiresX11Lock); } isInit = true; } @@ -101,19 +115,19 @@ public class X11Util { } } - public static boolean isFirstX11ActionOnProcess() { - return isFirstX11ActionOnProcess; + public static boolean requiresToolkitLock() { + return requiresX11Lock; } public static void lockDefaultToolkit(long dpyHandle) { NativeWindowFactory.getDefaultToolkitLock().lock(); - if(!isFirstX11ActionOnProcess) { + if(requiresX11Lock) { X11Util.XLockDisplay(dpyHandle); } } public static void unlockDefaultToolkit(long dpyHandle) { - if(!isFirstX11ActionOnProcess) { + if(requiresX11Lock) { X11Util.XUnlockDisplay(dpyHandle); } NativeWindowFactory.getDefaultToolkitLock().unlock(); @@ -124,11 +138,11 @@ public class X11Util { synchronized(X11Util.class) { if(null==nullDisplayName) { NativeWindowFactory.getDefaultToolkitLock().lock(); + long dpy = X11Lib.XOpenDisplay(null); try { - long dpy = X11Lib.XOpenDisplay(null); nullDisplayName = X11Lib.XDisplayString(dpy); - X11Lib.XCloseDisplay(dpy); } finally { + X11Lib.XCloseDisplay(dpy); NativeWindowFactory.getDefaultToolkitLock().unlock(); } if(DEBUG) { diff --git a/src/newt/classes/jogamp/newt/x11/X11Display.java b/src/newt/classes/jogamp/newt/x11/X11Display.java index 815395e2d..0804455d1 100644 --- a/src/newt/classes/jogamp/newt/x11/X11Display.java +++ b/src/newt/classes/jogamp/newt/x11/X11Display.java @@ -76,7 +76,7 @@ public class X11Display extends DisplayImpl { throw e; } - if(X11Util.XINITTHREADS_ALWAYS_ENABLED) { + if(X11Util.XINITTHREADS_ALWAYS_ENABLED && !X11Util.MULTITHREADING_BUG) { // Hack: Force non X11Display locking, even w/ AWT and w/o isFirstUIActionOnProcess() aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock()); } else { |