summaryrefslogtreecommitdiffstats
path: root/src/nativewindow
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-11-25 03:06:56 +0100
committerSven Gothel <[email protected]>2011-11-25 03:06:56 +0100
commit0314be79a7a93931a74fe4322bc78e699d7741e9 (patch)
treef5f9be82bc3c2acbf6f8122c60a5d2d1c3f5cc99 /src/nativewindow
parent9ef0a0c185ace5217efc014809e97c5eead842cc (diff)
NativeWindow X11 Locking: Fix XInitThreads/XLockDisplay/XUnlockDisplay Usage ;
XLockDisplay/XUnlockDisplay shall only be used if XInitThreads() was successful, otherwise it has no effect (X11 spec). - Only issue XInitThreads() if firstX11ActionOnProcess==true, store result to determing whether we can utilize XLockDisplay/XUnlockDisplay. - If we cannot utilize XLockDisplay/XUnlockDisplay, use RecursiveLock - NativeWindowFactory: Only return AWTToolkitLock or X11JAWTToolkitLock if explicitly requested
Diffstat (limited to 'src/nativewindow')
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java71
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java23
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java23
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java75
-rw-r--r--src/nativewindow/native/x11/Xmisc.c5
5 files changed, 118 insertions, 79 deletions
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index bbc915f2c..adc946f70 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -195,10 +195,9 @@ public abstract class NativeWindowFactory {
final ClassLoader cl = NativeWindowFactory.class.getClassLoader();
- if(firstUIActionOnProcess) {
- // X11 initialization before possible AWT initialization
- initNativeImpl(true, cl);
- }
+ // X11 initialization before possible AWT initialization
+ initNativeImpl(firstUIActionOnProcess, cl);
+
isAWTAvailable = false; // may be set to true below
if( !Debug.getBooleanProperty("java.awt.headless", true, acc) &&
@@ -230,10 +229,6 @@ public abstract class NativeWindowFactory {
}
}
}
- if(!firstUIActionOnProcess) {
- // X11 initialization after possible AWT initialization
- initNativeImpl(false, cl);
- }
registeredFactories = Collections.synchronizedMap(new HashMap<Class<?>, NativeWindowFactory>());
// register our default factory -> NativeWindow
@@ -324,31 +319,30 @@ public abstract class NativeWindowFactory {
* <ul>
* <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
* <ul>
- * <li>If native <b>X11 type</b> with or w/o AWT</li>
- * <ul>
- * <li> If <b>AWT available</b> </li>
+ * <li>If <b>AWT-type</b> and <b>native-X11-type</b> and <b>AWT-available</b></li>
* <ul>
* <li> return {@link jogamp.nativewindow.jawt.JAWTToolkitLock} </li>
* </ul>
- * </ul>
* </ul>
* <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
- /* package */ static ToolkitLock getDefaultToolkitLock(String type) {
+ public static ToolkitLock getDefaultToolkitLock(String type) {
if( requiresToolkitLock() ) {
- if( TYPE_X11 == type || TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) ) {
- if( isAWTAvailable() ) {
- return getAWTToolkitLock();
- }
+ if( TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) && isAWTAvailable() ) {
+ return getAWTToolkitLock();
}
}
return NativeWindowFactoryImpl.getNullToolkitLock();
}
- /* package */ static ToolkitLock getAWTToolkitLock() {
+ private static ToolkitLock getAWTToolkitLock() {
Object resO = ReflectionUtil.callMethod(null, jawtUtilGetJAWTToolkitMethod);
+ if(DEBUG) {
+ System.err.println("NativeWindowFactory.getAWTToolkitLock()");
+ Thread.dumpStack();
+ }
if(resO instanceof ToolkitLock) {
return (ToolkitLock) resO;
} else {
@@ -368,26 +362,49 @@ public abstract class NativeWindowFactory {
* <ul>
* <li>If <b>X11 type</b> </li>
* <ul>
- * <li> If <b>AWT available</b> </li>
+ * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
+ * </ul>
+ * </ul>
+ * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
+ * </ul>
+ */
+ public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) {
+ if( requiresToolkitLock() ) {
+ if( TYPE_X11 == type ) {
+ if( 0== deviceHandle ) {
+ throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
+ }
+ return createX11ToolkitLock(deviceHandle);
+ }
+ }
+ 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> If <b>shared-AWT-type</b> and <b>AWT available</b> </li>
* <ul>
* <li> return {@link jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock} </li>
* </ul>
- * <li> If <b>AWT not available</b> </li>
- * <ul>
- * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
- * </ul>
+ * <li> else return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
* </ul>
* </ul>
* <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
- public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) {
+ public static ToolkitLock createDefaultToolkitLock(String type, String sharedType, long deviceHandle) {
if( requiresToolkitLock() ) {
if( TYPE_X11 == type ) {
if( 0== deviceHandle ) {
throw new RuntimeException("JAWTUtil.createDefaultToolkitLock() called with NULL device but on X11");
}
- if( isAWTAvailable() ) {
+ if( TYPE_AWT == sharedType && isAWTAvailable() ) {
return createX11AWTToolkitLock(deviceHandle);
}
return createX11ToolkitLock(deviceHandle);
@@ -398,6 +415,10 @@ public abstract class NativeWindowFactory {
protected static ToolkitLock createX11AWTToolkitLock(long deviceHandle) {
try {
+ if(DEBUG) {
+ System.err.println("NativeWindowFactory.createX11AWTToolkitLock(0x"+Long.toHexString(deviceHandle)+")");
+ Thread.dumpStack();
+ }
return (ToolkitLock) x11JAWTToolkitLockConstructor.newInstance(new Object[]{new Long(deviceHandle)});
} catch (Exception ex) {
throw new RuntimeException(ex);
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
index 5d4fa0dad..94a71f5e6 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
@@ -31,6 +31,9 @@ import jogamp.nativewindow.jawt.*;
import jogamp.nativewindow.x11.X11Util;
import javax.media.nativewindow.ToolkitLock;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
/**
* Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
* utilizing JAWT's AWT lock via {@link JAWTUtil#lockToolkit()} and {@link X11Util#XLockDisplay(long)}.
@@ -41,20 +44,32 @@ import javax.media.nativewindow.ToolkitLock;
*/
public class X11JAWTToolkitLock implements ToolkitLock {
long displayHandle;
+ RecursiveLock lock;
public X11JAWTToolkitLock(long displayHandle) {
this.displayHandle = displayHandle;
+ if(!X11Util.isNativeLockAvailable()) {
+ lock = LockFactory.createRecursiveLock();
+ }
}
public final void lock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock()"); }
+ if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock() - native: "+(null==lock)); }
JAWTUtil.lockToolkit();
- X11Util.XLockDisplay(displayHandle);
+ if(null == lock) {
+ X11Util.XLockDisplay(displayHandle);
+ } else {
+ lock.lock();
+ }
}
public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock()"); }
- X11Util.XUnlockDisplay(displayHandle);
+ if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock() - native: "+(null==lock)); }
+ if(null == lock) {
+ X11Util.XUnlockDisplay(displayHandle);
+ } else {
+ lock.unlock();
+ }
JAWTUtil.unlockToolkit();
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
index fb0aff10d..974211261 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
@@ -29,6 +29,9 @@ package jogamp.nativewindow.x11;
import javax.media.nativewindow.ToolkitLock;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+
/**
* Implementing a recursive {@link javax.media.nativewindow.ToolkitLock}
* utilizing {@link X11Util#XLockDisplay(long)}.
@@ -38,18 +41,30 @@ import javax.media.nativewindow.ToolkitLock;
*/
public class X11ToolkitLock implements ToolkitLock {
long displayHandle;
+ RecursiveLock lock;
public X11ToolkitLock(long displayHandle) {
this.displayHandle = displayHandle;
+ if(!X11Util.isNativeLockAvailable()) {
+ lock = LockFactory.createRecursiveLock();
+ }
}
public final void lock() {
- if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock()"); }
- X11Util.XLockDisplay(displayHandle);
+ if(TRACE_LOCK) { System.err.println("X11ToolkitLock.lock() - native: "+(null==lock)); }
+ if(null == lock) {
+ X11Util.XLockDisplay(displayHandle);
+ } else {
+ lock.lock();
+ }
}
public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock()"); }
- X11Util.XUnlockDisplay(displayHandle);
+ if(TRACE_LOCK) { System.err.println("X11ToolkitLock.unlock() - native: "+(null==lock)); }
+ if(null == lock) {
+ X11Util.XUnlockDisplay(displayHandle);
+ } else {
+ lock.unlock();
+ }
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
index 0fd14bc6e..211967b5c 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -34,6 +34,7 @@
package jogamp.nativewindow.x11;
import com.jogamp.common.util.LongObjectHashMap;
+
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NWJNILibLoader;
@@ -66,13 +67,12 @@ public class X11Util {
*/
public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = true;
- 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 requiresX11Lock = false;
+ private static boolean isX11LockAvailable = false;
+ private static boolean requiresX11Lock = true;
private static boolean isInit = false;
private static boolean markAllDisplaysUnclosable = false; // ATI/AMD X11 driver issues
@@ -84,25 +84,22 @@ public class X11Util {
if(!isInit) {
NWJNILibLoader.loadNativeWindow("x11");
- /**
- * Always issue XInitThreads() since we have independent
- * off-thread created Display connections able to utilize multithreading,
- * ie NEWT (jogamp.newt.x11.X11Display.createNativeImpl()) !!
- */
- initialize0( XINITTHREADS_ALWAYS_ENABLED ? true : firstX11ActionOnProcess );
+ isX11LockAvailable = initialize0( firstX11ActionOnProcess );
- requiresX11Lock = !firstX11ActionOnProcess ;
-
if(DEBUG) {
System.err.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+
- ", XINITTHREADS_ALWAYS_ENABLED "+XINITTHREADS_ALWAYS_ENABLED+
- ", requiresX11Lock "+requiresX11Lock);
- // Thread.dumpStack();
+ ", requiresX11Lock "+requiresX11Lock+
+ ", isX11LockAvailable "+isX11LockAvailable);
+ Thread.dumpStack();
}
isInit = true;
}
}
+ public static synchronized boolean isNativeLockAvailable() {
+ return isX11LockAvailable;
+ }
+
public static synchronized boolean requiresToolkitLock() {
return requiresX11Lock;
}
@@ -127,16 +124,18 @@ public class X11Util {
}
public static void lockDefaultToolkit(long dpyHandle) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- if(requiresX11Lock) {
- X11Util.XLockDisplay(dpyHandle);
+ if(ToolkitLock.TRACE_LOCK) {
+ System.out.println("+++ X11 Display lockDefaultToolkit [x11Lock: "+isX11LockAvailable+"] get 0x"+Long.toHexString(dpyHandle));
}
+ NativeWindowFactory.getDefaultToolkitLock().lock();
+ X11Util.XLockDisplay(dpyHandle);
}
public static void unlockDefaultToolkit(long dpyHandle) {
- if(requiresX11Lock) {
- X11Util.XUnlockDisplay(dpyHandle);
+ if(ToolkitLock.TRACE_LOCK) {
+ System.out.println("+++ X11 Display lockDefaultToolkit [x11Lock: "+isX11LockAvailable+"] rel 0x"+Long.toHexString(dpyHandle));
}
+ X11Util.XUnlockDisplay(dpyHandle);
NativeWindowFactory.getDefaultToolkitLock().unlock();
}
@@ -225,7 +224,6 @@ public class X11Util {
public final void setUncloseable(boolean v) { unCloseable = v; }
public final boolean isUncloseable() { return unCloseable; }
-
public final Throwable getCreationStack() { return creationStack; }
@Override
@@ -245,14 +243,11 @@ public class X11Util {
public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) {
int num=0;
if(DEBUG||verbose||pendingDisplayList.size() > 0) {
- String msg = "X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
- ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
- ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")" ;
+ System.err.println("X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
+ ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
+ ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")");
if(DEBUG) {
- Exception e = new Exception(msg);
- e.printStackTrace();
- } else {
- System.err.println(msg);
+ Thread.dumpStack();
}
if( openDisplayList.size() > 0) {
X11Util.dumpOpenDisplayConnections();
@@ -385,8 +380,8 @@ public class X11Util {
}
}
if(DEBUG) {
- Exception e = new Exception("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+". Thread "+Thread.currentThread().getName());
- e.printStackTrace();
+ System.err.println("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+". Thread "+Thread.currentThread().getName());
+ // Thread.dumpStack();
}
return namedDpy.getHandle();
}
@@ -409,10 +404,6 @@ public class X11Util {
if(!openDisplayList.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
if(!namedDpy.isUncloseable()) {
- if(DEBUG) {
- System.err.println("X11Util.Display: XCloseDisplay "+namedDpy+". Thread "+Thread.currentThread().getName());
- Thread.dumpStack();
- }
XCloseDisplay(namedDpy.getHandle());
} else {
// for reuse
@@ -456,8 +447,8 @@ public class X11Util {
try {
long handle = X11Lib.XOpenDisplay(arg0);
if(TRACE_DISPLAY_LIFECYCLE) {
- Throwable t = new Throwable(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
- t.printStackTrace();
+ System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
+ // Thread.dumpStack();
}
return handle;
} finally {
@@ -469,8 +460,8 @@ public class X11Util {
NativeWindowFactory.getDefaultToolkitLock().lock();
try {
if(TRACE_DISPLAY_LIFECYCLE) {
- Throwable t = new Throwable(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
- t.printStackTrace();
+ System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
+ // Thread.dumpStack();
}
int res = -1;
X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
@@ -678,19 +669,13 @@ public class X11Util {
}
public static void XLockDisplay(long handle) {
- if(ToolkitLock.TRACE_LOCK) {
- System.out.println("+++ X11 Display Lock get 0x"+Long.toHexString(handle));
- }
X11Lib.XLockDisplay(handle);
- }
+ }
public static void XUnlockDisplay(long handle) {
- if(ToolkitLock.TRACE_LOCK) {
- System.out.println("--- X11 Display Lock rel 0x"+Long.toHexString(handle));
- }
X11Lib.XUnlockDisplay(handle);
}
- private static native void initialize0(boolean firstUIActionOnProcess);
+ private static native boolean initialize0(boolean firstUIActionOnProcess);
private static native void setX11ErrorHandler0(boolean onoff, boolean quiet);
}
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index d481343f9..8b56bca90 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -293,14 +293,16 @@ static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) {
}
static int _initialized=0;
+static jboolean _xinitThreadsOK=JNI_FALSE;
-JNIEXPORT void JNICALL
+JNIEXPORT jboolean JNICALL
Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass _unused, jboolean firstUIActionOnProcess) {
if(0==_initialized) {
if( JNI_TRUE == firstUIActionOnProcess ) {
if( 0 == XInitThreads() ) {
fprintf(stderr, "Warning: XInitThreads() failed\n");
} else {
+ _xinitThreadsOK=JNI_TRUE;
fprintf(stderr, "Info: XInitThreads() called for concurrent Thread support\n");
}
} else {
@@ -311,6 +313,7 @@ Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass _unused, jb
x11IOErrorHandlerEnable(1, env);
_initialized=1;
}
+ return _xinitThreadsOK;
}
JNIEXPORT void JNICALL