aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java89
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java6
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java77
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java176
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java10
5 files changed, 240 insertions, 118 deletions
diff --git a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
index d08fefa29..42e1c9be5 100644
--- a/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
@@ -29,8 +29,11 @@ package com.jogamp.newt.swt;
import java.awt.EventQueue;
+import javax.media.nativewindow.NativeWindowException;
+
import jogamp.newt.Debug;
+import com.jogamp.common.util.RunnableTask;
import com.jogamp.newt.util.EDTUtil;
/**
@@ -136,38 +139,58 @@ public class SWTEDTUtil implements EDTUtil {
if(task == null) {
throw new RuntimeException("Null Runnable");
}
- synchronized(edtLock) { // lock the EDT status
- if( nedt.shouldStop ) {
- // drop task ..
- if(DEBUG) {
- System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
- Thread.dumpStack();
+ Throwable throwable = null;
+ RunnableTask rTask = null;
+ Object rTaskLock = new Object();
+ synchronized(rTaskLock) { // lock the optional task execution
+ synchronized(edtLock) { // lock the EDT status
+ if( nedt.shouldStop ) {
+ // drop task ..
+ if(DEBUG) {
+ System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
+ Thread.dumpStack();
+ }
+ return;
}
- return;
- }
- // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
- // Thread.dumpStack();
- if(stop) {
- nedt.shouldStop = true;
- if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
- // Thread.dumpStack();
+ // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
+ // Thread.dumpStack();
+ if(stop) {
+ nedt.shouldStop = true;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
+ // Thread.dumpStack();
+ }
+ }
+ if( isCurrentThreadEDT() ) {
+ task.run();
+ wait = false; // running in same thread (EDT) -> no wait
+ } else if( swtDisplay.isDisposed() ) {
+ wait = false; // drop task, SWT disposed
+ } else {
+ // start if should not stop && not started yet
+ if( !stop && !nedt.isRunning() ) {
+ startImpl();
+ }
+ rTask = new RunnableTask(task,
+ wait ? rTaskLock : null,
+ true /* always catch and report Exceptions, don't disturb EDT */);
+ swtDisplay.asyncExec(rTask);
}
}
- if( isCurrentThreadEDT() ) {
- task.run();
- wait = false; // running in same thread (EDT) -> no wait
- } else if( swtDisplay.isDisposed() ) {
- wait = false; // drop task, SWT disposed
- } else {
- // start if should not stop && not started yet
- if( !stop && !nedt.isRunning() ) {
- startImpl();
+ if( wait ) {
+ try {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ } catch (InterruptedException ie) {
+ throwable = ie;
}
- if(wait) {
- swtDisplay.syncExec(task);
- } else {
- swtDisplay.asyncExec(task);
+ if(null==throwable) {
+ throwable = rTask.getThrowable();
+ }
+ if(null!=throwable) {
+ if(throwable instanceof NativeWindowException) {
+ throw (NativeWindowException)throwable;
+ }
+ throw new RuntimeException(throwable);
}
}
}
@@ -175,11 +198,12 @@ public class SWTEDTUtil implements EDTUtil {
@Override
final public void waitUntilIdle() {
- final NewtEventDispatchThread _edt;
+ final NewtEventDispatchThread _nedt;
synchronized(edtLock) {
- _edt = nedt;
+ _nedt = nedt;
}
- if(!_edt.isRunning() || EventQueue.isDispatchThread() || _edt == Thread.currentThread()) {
+ final Thread ct = Thread.currentThread();
+ if(!_nedt.isRunning() || _nedt == ct || swtDisplay.getThread() == ct) {
return;
}
try {
@@ -192,7 +216,8 @@ public class SWTEDTUtil implements EDTUtil {
@Override
final public void waitUntilStopped() {
synchronized(edtLock) {
- if(nedt.isRunning() && nedt != Thread.currentThread() ) {
+ final Thread ct = Thread.currentThread();
+ if(nedt.isRunning() && nedt != ct && swtDisplay.getThread() != ct) {
while(nedt.isRunning()) {
try {
edtLock.wait();
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index fbccc5767..317535805 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -366,12 +366,10 @@ public abstract class DisplayImpl extends Display {
private ArrayList<NEWTEventTask> events = new ArrayList<NEWTEventTask>();
private volatile boolean haveEvents = false;
- class DispatchMessagesRunnable implements Runnable {
+ final protected Runnable dispatchMessagesRunnable = new Runnable() {
public void run() {
DisplayImpl.this.dispatchMessages();
- }
- }
- protected DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable();
+ } };
final void dispatchMessage(final NEWTEventTask eventTask) {
final NEWTEvent event = eventTask.get();
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
index 01b5ad8a4..2175f2190 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
@@ -30,6 +30,9 @@ package jogamp.newt.driver.awt;
import java.awt.EventQueue;
+import javax.media.nativewindow.NativeWindowException;
+
+import com.jogamp.common.util.RunnableTask;
import com.jogamp.newt.util.EDTUtil;
import jogamp.common.awt.AWTEDTExecutor;
@@ -124,33 +127,57 @@ public class AWTEDTUtil implements EDTUtil {
if(task == null) {
throw new RuntimeException("Null Runnable");
}
- synchronized(edtLock) { // lock the EDT status
- if( nedt.shouldStop ) {
- // drop task ..
- if(DEBUG) {
- System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
- Thread.dumpStack();
+ Throwable throwable = null;
+ RunnableTask rTask = null;
+ Object rTaskLock = new Object();
+ synchronized(rTaskLock) { // lock the optional task execution
+ synchronized(edtLock) { // lock the EDT status
+ if( nedt.shouldStop ) {
+ // drop task ..
+ if(DEBUG) {
+ System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+nedt);
+ Thread.dumpStack();
+ }
+ return;
}
- return;
- }
- // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
- // Thread.dumpStack();
- if(stop) {
- nedt.shouldStop = true;
- if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
- // Thread.dumpStack();
+ // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
+ // Thread.dumpStack();
+ if(stop) {
+ nedt.shouldStop = true;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
+ // Thread.dumpStack();
+ }
+ }
+ if( isCurrentThreadEDT() ) {
+ task.run();
+ wait = false; // running in same thread (EDT) -> no wait
+ } else {
+ // start if should not stop && not started yet
+ if( !stop && !nedt.isRunning() ) {
+ startImpl();
+ }
+ rTask = new RunnableTask(task,
+ wait ? rTaskLock : null,
+ true /* always catch and report Exceptions, don't disturb EDT */);
+ AWTEDTExecutor.singleton.invoke(false, rTask);
}
}
- if( isCurrentThreadEDT() ) {
- task.run();
- wait = false; // running in same thread (EDT) -> no wait
- } else {
- // start if should not stop && not started yet
- if( !stop && !nedt.isRunning() ) {
- startImpl();
+ if( wait ) {
+ try {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ } catch (InterruptedException ie) {
+ throwable = ie;
+ }
+ if(null==throwable) {
+ throwable = rTask.getThrowable();
+ }
+ if(null!=throwable) {
+ if(throwable instanceof NativeWindowException) {
+ throw (NativeWindowException)throwable;
+ }
+ throw new RuntimeException(throwable);
}
- AWTEDTExecutor.singleton.invoke(wait, task);
}
}
}
@@ -161,7 +188,7 @@ public class AWTEDTUtil implements EDTUtil {
synchronized(edtLock) {
_edt = nedt;
}
- if(!_edt.isRunning() || EventQueue.isDispatchThread() || _edt == Thread.currentThread()) {
+ if(!_edt.isRunning() || _edt == Thread.currentThread() || EventQueue.isDispatchThread()) {
return;
}
try {
@@ -174,7 +201,7 @@ public class AWTEDTUtil implements EDTUtil {
@Override
final public void waitUntilStopped() {
synchronized(edtLock) {
- if(nedt.isRunning() && nedt != Thread.currentThread() ) {
+ if(nedt.isRunning() && nedt != Thread.currentThread() && !EventQueue.isDispatchThread()) {
while(nedt.isRunning()) {
try {
edtLock.wait();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java
index 3b5c4267e..9c0762c12 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTBug628ResizeDeadlock.java
@@ -35,12 +35,11 @@ import java.lang.reflect.InvocationTargetException;
import org.eclipse.swt.SWT ;
import org.eclipse.swt.layout.FillLayout ;
-import org.eclipse.swt.layout.GridData ;
-import org.eclipse.swt.layout.GridLayout ;
import org.eclipse.swt.widgets.Composite ;
import org.eclipse.swt.widgets.Display ;
import org.eclipse.swt.widgets.Shell ;
+import org.junit.Assume;
import org.junit.Test;
import javax.media.opengl.GL ;
@@ -52,6 +51,7 @@ import javax.media.opengl.GLProfile;
import junit.framework.Assert;
+import com.jogamp.nativewindow.swt.SWTAccessor;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow ;
@@ -142,7 +142,7 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
////////////////////////////////////////////////////////////////////////////////
static class ResizeThread extends Thread {
- boolean shallStop = false;
+ volatile boolean shallStop = false;
private Shell _shell ;
private int _n ;
@@ -152,6 +152,26 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
_shell = shell ;
}
+ final Runnable resizeAction = new Runnable() {
+ public void run()
+ {
+ System.err.println("[R-i shallStop "+shallStop+", disposed "+_shell.isDisposed()+"]");
+ if( shallStop || _shell.isDisposed() ) {
+ return;
+ }
+ try {
+ if( _n % 2 == 0 ) {
+ _shell.setSize( 200, 200 ) ;
+ } else {
+ _shell.setSize( 400, 450 ) ;
+ }
+ } catch (Exception e0) {
+ e0.printStackTrace();
+ Assert.assertTrue("Deadlock @ setSize: "+e0, false);
+ }
+ ++_n ;
+ } };
+
public void run()
{
// The problem was originally observed by grabbing the lower right
@@ -162,33 +182,24 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
// This loop simulates rapid resizing by the user by toggling
// the shell back-and-forth between two sizes.
- while( !shallStop )
+ System.err.println("[R-0 shallStop "+shallStop+", disposed "+_shell.isDisposed()+"]");
+
+ final Display display = _shell.getDisplay();
+
+ while( !shallStop && !_shell.isDisposed() )
{
try
{
- _shell.getDisplay().asyncExec( new Runnable()
- {
- public void run()
- {
- try {
- if( _n % 2 == 0 ) {
- _shell.setSize( 200, 200 ) ;
- } else {
- _shell.setSize( 400, 450 ) ;
- }
- } catch (Exception e0) {
- e0.printStackTrace();
- Assert.assertTrue("Deadlock @ setSize: "+e0, false);
- }
- ++_n ;
- }
- } ) ;
+ System.err.println("[R-n shallStop "+shallStop+", disposed "+_shell.isDisposed()+"]");
+ display.asyncExec( resizeAction );
+ display.wake();
- Thread.sleep( 50L ) ;
+ Thread.sleep( 50L ) ;
} catch( InterruptedException e ) {
break ;
}
}
+ System.err.println("*R-Exit* shallStop "+shallStop+", disposed "+_shell.isDisposed());
}
}
@@ -196,50 +207,101 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
static class KeyfireThread extends Thread
{
- boolean shallStop = false;
+ volatile boolean shallStop = false;
+ Display _display;
Robot _robot;
int _n = 0;
- public KeyfireThread(Robot robot)
+ public KeyfireThread(Robot robot, Display display)
{
_robot = robot;
+ _display = display;
}
public void run()
{
+ System.err.println("[K-0]");
+
while( !shallStop )
{
try {
+ System.err.println("[K-"+_n+"]");
AWTRobotUtil.keyPress(_n, _robot, true, KeyEvent.VK_0, 10);
AWTRobotUtil.keyPress(_n, _robot, false, KeyEvent.VK_0, 0);
Thread.sleep( 40L ) ;
+ _n++;
+ if(!_display.isDisposed()) {
+ _display.wake();
+ }
} catch( InterruptedException e ) {
break ;
}
}
+ System.err.println("*K-Exit*");
}
}
////////////////////////////////////////////////////////////////////////////////
+ private volatile boolean shallStop = false;
+
+ static class SWT_DSC {
+ Display display;
+ Shell shell;
+ Composite composite;
+
+ public void init() {
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ display = new Display();
+ Assert.assertNotNull( display );
+ }});
+
+ display.syncExec(new Runnable() {
+ public void run() {
+ shell = new Shell( display );
+ Assert.assertNotNull( shell );
+ shell.setLayout( new FillLayout() );
+ composite = new Composite( shell, SWT.NONE );
+ composite.setLayout( new FillLayout() );
+ Assert.assertNotNull( composite );
+ }});
+ }
+
+ public void dispose() {
+ Assert.assertNotNull( display );
+ Assert.assertNotNull( shell );
+ Assert.assertNotNull( composite );
+ try {
+ display.syncExec(new Runnable() {
+ public void run() {
+ composite.dispose();
+ shell.dispose();
+ }});
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ display.dispose();
+ }});
+ }
+ catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ display = null;
+ shell = null;
+ composite = null;
+ }
+ }
+
@Test
public void test() throws InterruptedException, AWTException, InvocationTargetException {
- final int columnCount = 1;
- final Display display = new Display() ;
-
- final Shell shell = new Shell( display ) ;
- shell.setLayout( new FillLayout() ) ;
-
final Robot robot = new Robot();
- Composite composite = new Composite( shell, SWT.NONE ) ;
- {
- GridLayout layout = new GridLayout() ;
- layout.numColumns = columnCount ;
- composite.setLayout( layout ) ;
- }
-
+ final SWT_DSC dsc = new SWT_DSC();
+ dsc.init();
+
final GLWindow glWindow;
+ final NewtCanvasSWT canvas;
{
final GLProfile gl2Profile = GLProfile.get( GLProfile.GL2 ) ;
GLCapabilities caps = new GLCapabilities( gl2Profile ) ;
@@ -252,26 +314,30 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
glWindow.display();
}
});
- NewtCanvasSWT canvas = NewtCanvasSWT.create( composite, SWT.NO_BACKGROUND, glWindow ) ;
- canvas.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true, columnCount, 1 ) ) ;
+ canvas = NewtCanvasSWT.create( dsc.composite, 0, glWindow ) ;
}
- shell.setText( "NewtCanvasSWT Resize Bug Demo" ) ;
- shell.setSize( 400, 450 ) ;
- shell.open() ;
-
+ dsc.display.syncExec( new Runnable() {
+ public void run() {
+ dsc.shell.setText( "NewtCanvasSWT Resize Bug Demo" ) ;
+ dsc.shell.setSize( 400, 450 ) ;
+ dsc.shell.open() ;
+ } } );
+
AWTRobotUtil.requestFocus(robot, glWindow, false);
AWTRobotUtil.setMouseToClientLocation(robot, glWindow, 50, 50);
+ shallStop = false;
+
final ResizeThread resizer;
{
- resizer = new ResizeThread( shell ) ;
+ resizer = new ResizeThread( dsc.shell ) ;
resizer.start() ;
}
final KeyfireThread keyfire;
{
- keyfire = new KeyfireThread( robot ) ;
+ keyfire = new KeyfireThread( robot, dsc.display ) ;
keyfire.start() ;
}
@@ -292,18 +358,15 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
{
keyfire.join();
} catch( InterruptedException e ) { }
- display.syncExec( new Runnable() {
- @Override
- public void run() {
- shell.dispose();
- } } );
+ shallStop = true;
+ dsc.display.wake();
} } ).start();
}
-
+
try {
- while( !shell.isDisposed() ) {
- if( !display.readAndDispatch() ) {
- display.sleep();
+ while( !shallStop && !dsc.display.isDisposed() ) {
+ if( !dsc.display.readAndDispatch() ) {
+ dsc.display.sleep();
}
}
} catch (Exception e0) {
@@ -311,7 +374,10 @@ public class TestNewtCanvasSWTBug628ResizeDeadlock extends UITestCase {
Assert.assertTrue("Deadlock @ dispatch: "+e0, false);
}
- display.dispose() ;
+ System.err.println("NewtCanvasAWT Dispose");
+ canvas.dispose();
+
+ dsc.dispose();
}
public static void main( String[] args ) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java
index 61caa5ef9..396d219b4 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestNewtCanvasSWTGLn.java
@@ -93,6 +93,9 @@ public class TestNewtCanvasSWTGLn extends UITestCase {
public void run() {
display = new Display();
Assert.assertNotNull( display );
+ }});
+ display.syncExec(new Runnable() {
+ public void run() {
shell = new Shell( display );
Assert.assertNotNull( shell );
shell.setLayout( new FillLayout() );
@@ -108,10 +111,13 @@ public class TestNewtCanvasSWTGLn extends UITestCase {
Assert.assertNotNull( shell );
Assert.assertNotNull( composite );
try {
- SWTAccessor.invoke(true, new Runnable() {
+ display.syncExec(new Runnable() {
public void run() {
composite.dispose();
shell.dispose();
+ }});
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
display.dispose();
}});
}
@@ -149,7 +155,7 @@ public class TestNewtCanvasSWTGLn extends UITestCase {
final NewtCanvasSWT canvas1 = NewtCanvasSWT.create( composite, 0, postAttach ? null : glWindow1 );
Assert.assertNotNull( canvas1 );
- SWTAccessor.invoke(true, new Runnable() {
+ display.syncExec( new Runnable() {
public void run() {
shell.setText( getSimpleTestName(".") );
shell.setSize( 640, 480 );