summaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-11-27 01:55:10 +0100
committerSven Gothel <[email protected]>2012-11-27 01:55:10 +0100
commit17dd761d7c2b224f0505a399bf4ecb18634e9250 (patch)
treed7cf306da5cf1f27e0f43a3f4de868ad9d7afc65 /src/newt
parent8cf694c1424277e6358039a964ecd75c54cf9af9 (diff)
SWTEDTUtil/AWTEDTUtil: Fix deadlock situations ; Cleanup TestNewtCanvasSWTBug628ResizeDeadlock
- Fix deadlock situation in waitUntilStopped/Idle(), skip if on AWT/SWT EDT - Use RunnableTask for sync task invocation, don't block AWT/SWT EDT. - Cleanup TestNewtCanvasSWTBug628ResizeDeadlock (works on OSX as well)
Diffstat (limited to 'src/newt')
-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
3 files changed, 111 insertions, 61 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();