From 9ed513e9a9616f6028084df4c650c8caf31ea49d Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 30 Aug 2011 03:50:31 +0200 Subject: Workaround (Fix) for Bug 502: Multithreading issue w/ libX11 1.4.2 and libxcb 1.7 bug 20708 See https://jogamp.org/bugzilla/show_bug.cgi?id=502 Since the libX11/xcb code doesn't seem to be fixed anytime soon a better usable workaround is required than using a system property to enable 'over locking'. It turns out that the race condition is related to the parallel X11 Display connection usage of GLX/OpenGL and event dispatching. This workaround utilizes 2 X11 Display handles, one for windowing/OpenGL and one for event dispatching. This approach allows us to cont. multithreading use w/o locking the display and works on both implementations, the old bug-free libX11 and the 'new' buggy one. Downside is the little resource overhead of the 2nd X11 Display connection .. well. - Removes the property: 'nativewindow.x11.mt-bug' --- .../classes/jogamp/nativewindow/x11/X11Util.java | 18 ++------- .../classes/jogamp/newt/driver/x11/X11Display.java | 45 +++++++++++++++++----- .../classes/jogamp/newt/driver/x11/X11Window.java | 8 ++-- src/newt/native/X11Window.c | 42 ++++++++++++-------- 4 files changed, 69 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java index 117184a71..37056d44d 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -51,15 +51,6 @@ 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 nativewindow.x11.mt-bug 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"); @@ -84,12 +75,11 @@ public class X11Util { */ initialize0( XINITTHREADS_ALWAYS_ENABLED ? true : firstX11ActionOnProcess ); - requiresX11Lock = !firstX11ActionOnProcess || MULTITHREADING_BUG; + requiresX11Lock = !firstX11ActionOnProcess ; if(DEBUG) { System.out.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+ ", XINITTHREADS_ALWAYS_ENABLED "+XINITTHREADS_ALWAYS_ENABLED+ - ", MULTITHREADING_BUG "+MULTITHREADING_BUG+ ", requiresX11Lock "+requiresX11Lock); } isInit = true; @@ -160,8 +150,8 @@ public class X11Util { // which is to tag a NamedDisplay uncloseable after creation. private static Object globalLock = new Object(); private static LongObjectHashMap globalNamedDisplayMap = new LongObjectHashMap(); - private static List openDisplayList = new ArrayList(); - private static List pendingDisplayList = new ArrayList(); + private static List openDisplayList = new ArrayList(); + private static List pendingDisplayList = new ArrayList(); public static class NamedDisplay { String name; @@ -269,7 +259,7 @@ public class X11Util { synchronized(globalLock) { System.err.println("X11Util: Open X11 Display Connections: "+openDisplayList.size()); for(int i=0; iNewGlobalRef(env, obj)); - NewtWindows_setDecorations(dpy, window, ( JNI_TRUE == undecorated ) ? False : True ); XSync(dpy, False); + XSetWMProtocols(dpyEDT, window, &wm_delete_atom, 1); + setJavaWindowProperty(env, dpyEDT, window, javaObjectAtom, (*env)->NewGlobalRef(env, obj)); + + { + long xevent_mask = 0; + xevent_mask |= ButtonPressMask | ButtonReleaseMask | PointerMotionMask ; + xevent_mask |= KeyPressMask | KeyReleaseMask ; + xevent_mask |= FocusChangeMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask ; + + XSelectInput(dpyEDT, window, xevent_mask); + } + XSync(dpyEDT, False); + DBG_PRINT( "X11: [CreateWindow] created window %p on display %p\n", (void*)window, dpy); return (jlong) window; } @@ -1394,9 +1401,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0 * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0 - (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom, jlong wmDeleteAtom) + (JNIEnv *env, jobject obj, jlong display, jlong displayEDT, jlong window, jlong javaObjectAtom, jlong wmDeleteAtom) { Display * dpy = (Display *) (intptr_t) display; + Display * dpyEDT = (Display *) (intptr_t) displayEDT; Window w = (Window)window; jobject jwindow; @@ -1406,7 +1414,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0 DBG_PRINT( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w); - jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True); + jwindow = getJavaWindowProperty(env, dpyEDT, w, javaObjectAtom, True); if(NULL==jwindow) { NewtCommon_throwNewRuntimeException(env, "could not fetch Java Window object, bail out!"); return; @@ -1417,11 +1425,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0 } XSync(dpy, False); - XSelectInput(dpy, w, 0); + XSelectInput(dpyEDT, w, 0); XUnmapWindow(dpy, w); // Drain all events related to this window .. - Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0(env, obj, display, javaObjectAtom, wmDeleteAtom); + Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0(env, obj, displayEDT, javaObjectAtom, wmDeleteAtom); XDestroyWindow(dpy, w); XSync(dpy, False); -- cgit v1.2.3