diff options
author | Sven Gothel <[email protected]> | 2013-06-24 15:50:27 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-06-24 15:50:27 +0200 |
commit | 8f3b2a4cc14be60681a7bfae0507655cc5702836 (patch) | |
tree | 2de704ed3f51fe73620e8f38c29988caa7bd600c | |
parent | c27157bf7fa9776b0f212c2ccfcf80c4e734eedc (diff) |
Workaroung a Java7 AWT EDT/Robot bug: Validate whether AWT-EDT is alive before certain robot ops.
We have experienced that w/o utilizing AWT components, i.e. NEWT tests,
the AWT-EDT 'sometimes' dies.
Performing AWT robot's waitForIdle() in this situation causes a deadlock,
since the call will never complete it's EventQueue.invokeAndWait() call.
While analyzing this issue, we created a test tool whether the the AWT EDT is still alive.
This test issues EventQueue.invokeLater( .. { flag=true; } ); and polls up until 2s
for the result.
Turns out that the sporadic AWT-EDT issues are solved by this test itself,
i.e. it probably cause it to be reinstated. (?!)
We have to observe this behavior.
Another proof that quantum mechanic rules also apply in the macro cosmos :)
-rwxr-xr-x | make/scripts/tests-win.bat | 4 | ||||
-rw-r--r-- | make/scripts/tests.sh | 4 | ||||
-rw-r--r-- | src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java | 9 | ||||
-rw-r--r-- | src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java | 53 |
4 files changed, 63 insertions, 7 deletions
diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat index dfe7b2887..f8cecf46b 100755 --- a/make/scripts/tests-win.bat +++ b/make/scripts/tests-win.bat @@ -72,7 +72,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestListenerCom01AWT REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.event.TestNewtKeyEventOrderAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.event.TestNewtKeyCodeModifiersAWT %* -REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.event.TestNewtKeyEventAutoRepeatAWT %* +scripts\java-win.bat com.jogamp.opengl.test.junit.newt.event.TestNewtKeyEventAutoRepeatAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.event.TestNewtKeyPressReleaseUnmaskRepeatAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.event.TestNewtKeyCodesAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.event.TestNewtEventModifiersNEWTWindowAWT $* @@ -95,7 +95,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.parenting.TestParenti REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.parenting.TestTranslucentParentingAWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.parenting.TestTranslucentChildWindowBug632NEWT %* -scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn %* +REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTBug628ResizeDeadlock %* diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index defb61e50..247cf9d2d 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -465,7 +465,7 @@ function testawtswt() { # with OSX: -XstartOnFirstThread # #testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTEclipseGLCanvas01GLn $* -testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn $* +#testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn $* #testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn $* #testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn $* #testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTBug628ResizeDeadlockAWT $* @@ -479,7 +479,7 @@ testawtswt com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn $* #testawt com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot $* #testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $* #testawt com.jogamp.opengl.test.junit.newt.event.TestNewtKeyEventOrderAWT $* -#testawt com.jogamp.opengl.test.junit.newt.event.TestNewtKeyEventAutoRepeatAWT $* +testawt com.jogamp.opengl.test.junit.newt.event.TestNewtKeyEventAutoRepeatAWT $* #testawt com.jogamp.opengl.test.junit.newt.event.TestNewtKeyPressReleaseUnmaskRepeatAWT $* #testawt com.jogamp.opengl.test.junit.newt.event.TestNewtKeyCodesAWT $* #testawt com.jogamp.opengl.test.junit.newt.event.TestNewtKeyCodeModifiersAWT $* diff --git a/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java b/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java index 3a2c4cc81..e6edd0da5 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/event/BaseNewtEventModifiers.java @@ -39,6 +39,7 @@ import org.junit.Test ; import com.jogamp.common.util.RunnableTask; import com.jogamp.newt.event.MouseEvent; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; import com.jogamp.opengl.test.junit.util.UITestCase ; /** @@ -519,7 +520,7 @@ public abstract class BaseNewtEventModifiers extends UITestCase { private void _doHoldOneButtonAndPressAnother( final int keyCode, final int keyModifierMask ) throws Exception { if( _debug ) { _debugPrintStream.println( "\n>>>> _doHoldOneButtonAndPressAnother" ) ; } - + _doKeyPress( keyCode ) ; for (int n = 0 ; n < _numButtonsToTest ; ++n) { @@ -561,7 +562,7 @@ public abstract class BaseNewtEventModifiers extends UITestCase { private void _doPressAllButtonsInSequence( final int keyCode, final int keyModifierMask ) throws Exception { if( _debug ) { _debugPrintStream.println( "\n>>>> _doPressAllButtonsInSequence" ) ; } - + _doKeyPress( keyCode ) ; { @@ -634,6 +635,7 @@ public abstract class BaseNewtEventModifiers extends UITestCase { //////////////////////////////////////////////////////////////////////////// private void _doKeyPress( int keyCode ) { + AWTRobotUtil.validateAWTEDTIsAlive(); if( keyCode != 0 ) { boolean modifierCheckEnabled = _testMouseListener.modifierCheckEnabled() ; _testMouseListener.setModifierCheckEnabled( false ) ; @@ -646,6 +648,7 @@ public abstract class BaseNewtEventModifiers extends UITestCase { //////////////////////////////////////////////////////////////////////////// private void _doKeyRelease( int keyCode ) { + AWTRobotUtil.validateAWTEDTIsAlive(); if( keyCode != 0 ) { boolean modifierCheckEnabled = _testMouseListener.modifierCheckEnabled() ; _testMouseListener.setModifierCheckEnabled( false ) ; @@ -697,6 +700,7 @@ public abstract class BaseNewtEventModifiers extends UITestCase { private void _releaseModifiers() { if (_robot != null) { + AWTRobotUtil.validateAWTEDTIsAlive(); _robot.setAutoDelay( MS_ROBOT_AUTO_DELAY ) ; @@ -721,6 +725,7 @@ public abstract class BaseNewtEventModifiers extends UITestCase { private void _escape() { if (_robot != null) { + AWTRobotUtil.validateAWTEDTIsAlive(); _robot.keyPress( java.awt.event.KeyEvent.VK_ESCAPE ) ; _robot.keyRelease( java.awt.event.KeyEvent.VK_ESCAPE ) ; } diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java index b5f8def3c..8a73d3363 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java @@ -31,8 +31,10 @@ package com.jogamp.opengl.test.junit.util; import jogamp.newt.WindowImplAccess; import jogamp.newt.awt.event.AWTNewtEventFactory; +import java.lang.Thread.UncaughtExceptionHandler; import java.lang.reflect.InvocationTargetException; import java.awt.AWTException; +import java.awt.EventQueue; import java.awt.Robot; import javax.media.nativewindow.NativeWindow; @@ -56,6 +58,50 @@ public class AWTRobotUtil { public static final int TIME_SLICE = TIME_OUT / POLL_DIVIDER ; public static Integer AWT_CLICK_TO = null; + static Object awtEDTAliveSync = new Object(); + static volatile boolean awtEDTAliveFlag = false; + + static class OurUncaughtExceptionHandler implements UncaughtExceptionHandler { + @Override + public void uncaughtException(Thread t, Throwable e) { + System.err.println("*** AWTRobotUtil: UncaughtException (this Thread "+Thread.currentThread().getName()+") : Thread <"+t.getName()+">, "+e.getClass().getName()+": "+e.getMessage()); + e.printStackTrace(); + } + } + + static { + Thread.setDefaultUncaughtExceptionHandler( new OurUncaughtExceptionHandler() ); + // System.err.println("AWT EDT alive: "+isAWTEDTAlive()); + } + + public static boolean isAWTEDTAlive() { + if( EventQueue.isDispatchThread() ) { + return true; + } + synchronized ( awtEDTAliveSync ) { + awtEDTAliveFlag = false; + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + awtEDTAliveFlag = true; + } + }); + for (int wait=0; wait<POLL_DIVIDER && !awtEDTAliveFlag; wait++) { + try { + Thread.sleep(TIME_SLICE); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return awtEDTAliveFlag; + } + } + public static void validateAWTEDTIsAlive() { + if( !isAWTEDTAlive() ) { + throw new Error("AWT EDT not alive"); + } + } + public static void clearAWTFocus(Robot robot) throws InterruptedException, InvocationTargetException, AWTException { if(null == robot) { robot = new Robot(); @@ -247,6 +293,7 @@ public class AWTRobotUtil { final int mouseButton = java.awt.event.InputEvent.BUTTON1_MASK; centerMouse(robot, obj, onTitleBarIfWindow); + validateAWTEDTIsAlive(); robot.waitForIdle(); robot.mousePress(mouseButton); robot.mouseRelease(mouseButton); @@ -279,6 +326,7 @@ public class AWTRobotUtil { public static void requestFocus(Robot robot, Object obj, int x, int y) throws AWTException, InterruptedException, InvocationTargetException { + validateAWTEDTIsAlive(); final boolean idling = robot.isAutoWaitForIdle(); final int mouseButton = java.awt.event.InputEvent.BUTTON1_MASK; @@ -395,12 +443,14 @@ public class AWTRobotUtil { } private static void awtRobotKeyPress(final Robot robot, final int keyCode, final int msDelay) { + validateAWTEDTIsAlive(); robot.waitForIdle(); robot.keyPress(keyCode); robot.delay(msDelay); robot.waitForIdle(); } private static void awtRobotKeyRelease(final Robot robot, final int keyCode, final int msDelay) { + validateAWTEDTIsAlive(); robot.waitForIdle(); robot.keyRelease(keyCode); robot.delay(msDelay); @@ -540,8 +590,9 @@ public class AWTRobotUtil { if(DEBUG) { System.err.println(i+":"+j+" MC1.0: "+counter+" - regain focus"); } requestFocus(null, obj); } - final int c0 = null != counter ? counter.getCount() : 0; + final int c0 = null != counter ? counter.getCount() : 0; if(DEBUG) { System.err.println(i+":"+j+" MC1.1: "+counter); } + validateAWTEDTIsAlive(); robot.waitForIdle(); robot.mousePress(mouseButton); robot.mouseRelease(mouseButton); |