|
From: Elias N. <eli...@us...> - 2005-10-23 19:41:16
|
Update of /cvsroot/java-game-lib/LWJGL/src/java/org/lwjgl/opengl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1927/src/java/org/lwjgl/opengl Modified Files: LinuxDisplay.java Log Message: Linux: Don't assume JAWT Lock()/Unlock() are re-entrant, fixing a hang with GCJ 4 Index: LinuxDisplay.java =================================================================== RCS file: /cvsroot/java-game-lib/LWJGL/src/java/org/lwjgl/opengl/LinuxDisplay.java,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- LinuxDisplay.java 10 Jul 2005 20:15:55 -0000 1.28 +++ LinuxDisplay.java 23 Oct 2005 19:41:08 -0000 1.29 @@ -49,16 +49,61 @@ final class LinuxDisplay implements DisplayImplementation { private static final int NUM_BUTTONS = 3; + /** Keep track on the current awt lock owner to avoid + * depending on JAWT locking to be re-entrant (This is a + * problem with GCJ). JAWT locking is not that well specified + * anyway so it is probably best to avoid assuming too much + * about it. + */ + private static Thread current_awt_lock_owner; + private static int awt_lock_count; + private static int display_connection_usage_count = 0; private static PeerInfo peer_info; /* Since Xlib is not guaranteed to be thread safe, we need a way to synchronize LWJGL - * Xlib calls with AWT Xlib calls. Fortunately, JAWT implements LockAWT and UnlockAWT() to + * Xlib calls with AWT Xlib calls. Fortunately, JAWT implements Lock()/Unlock() to * do just that. */ - static native void lockAWT(); - static native void unlockAWT(); + static synchronized void lockAWT() { + Thread this_thread = Thread.currentThread(); + while (current_awt_lock_owner != null && current_awt_lock_owner != this_thread) { + try { + LinuxDisplay.class.wait(); + } catch (InterruptedException e) { + LWJGLUtil.log("Interrupted while waiting for awt lock: " + e); + } + } + if (awt_lock_count == 0) { + current_awt_lock_owner = this_thread; + try { + nLockAWT(); + } catch (LWJGLException e) { + LWJGLUtil.log("Caught exception while locking AWT: " + e); + } + } + awt_lock_count++; + } + private static native void nLockAWT() throws LWJGLException; + + static synchronized void unlockAWT() { + if (awt_lock_count <= 0) + throw new IllegalStateException("AWT not locked!"); + if (Thread.currentThread() != current_awt_lock_owner) + throw new IllegalStateException("AWT already locked by " + current_awt_lock_owner); + awt_lock_count--; + if (awt_lock_count == 0) { + try { + nUnlockAWT(); + } catch (LWJGLException e) { + LWJGLUtil.log("Caught exception while unlocking AWT: " + e); + } + current_awt_lock_owner = null; + LinuxDisplay.class.notify(); + } + } + private static native void nUnlockAWT() throws LWJGLException; /** * increment and decrement display usage. |