Skip to content

Commit

Permalink
SWTEDTUtil/AWTEDTUtil: Fix deadlock situations ; Cleanup TestNewtCanv…
Browse files Browse the repository at this point in the history
…asSWTBug628ResizeDeadlock

- 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)
  • Loading branch information
sgothel committed Nov 27, 2012
1 parent 8cf694c commit 17dd761
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 121 deletions.
4 changes: 2 additions & 2 deletions make/scripts/make.jogl.all.win64.bat
Expand Up @@ -6,8 +6,8 @@ set ANT_PATH=C:\apache-ant-1.8.2

set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw64\bin;%PATH%

set LIB_GEN=%THISDIR%\lib
set CLASSPATH=.;%THISDIR%\build-win64\classes
REM set LIB_GEN=%THISDIR%\lib
REM set CLASSPATH=.;%THISDIR%\build-win64\classes
REM -Dc.compiler.debug=true
REM -Dsetup.addNativeOpenMAX=true
REM -Dsetup.addNativeKD=true
Expand Down
File renamed without changes.
7 changes: 7 additions & 0 deletions make/scripts/tests-macosx64-junit-swt.sh
@@ -0,0 +1,7 @@
#! /bin/bash

SDIR=`dirname $0`

. $SDIR/make.jogl.all.macosx.sh -f build-test.xml junit.run.settings junit.run.swt.awt


7 changes: 7 additions & 0 deletions make/scripts/tests-win64-junit-swt.bat
@@ -0,0 +1,7 @@
set THISDIR=%cd%

set SDIR=%~dp0%

%SDIR%/make.jogl.all.win64.bat -f build-test.xml junit.run.settings junit.run.swt.awt


3 changes: 2 additions & 1 deletion make/scripts/tests-x64.bat
Expand Up @@ -56,6 +56,7 @@ REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.parenting.TestP
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTAccessor03AWTGLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestSWTJOGLGLCanvas01GLn %*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTGLn %*
scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.swt.TestNewtCanvasSWTBug628ResizeDeadlock %*

REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestWindows01NEWT
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT
Expand Down Expand Up @@ -112,7 +113,7 @@ REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGPUMemSec01NEWT %*
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestMapBuffer01NEWT

scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateOnOffscrnCapsNEWT $*
REM scripts\java-win64-dbg.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableDelegateOnOffscrnCapsNEWT $*
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT $*
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableGLCanvasOnOffscrnCapsAWT $*
REM scripts\java-win64.bat com.jogamp.opengl.test.junit.jogl.acore.TestGLAutoDrawableFactoryOffscrnCapsNEWT $*
Expand Down
89 changes: 57 additions & 32 deletions src/newt/classes/com/jogamp/newt/swt/SWTEDTUtil.java
Expand Up @@ -29,8 +29,11 @@

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;

/**
Expand Down Expand Up @@ -136,50 +139,71 @@ private void invokeImpl(boolean wait, Runnable task, boolean stop) {
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);
}
}
}
}

@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 {
Expand All @@ -192,7 +216,8 @@ public void run() { }
@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();
Expand Down
6 changes: 2 additions & 4 deletions src/newt/classes/jogamp/newt/DisplayImpl.java
Expand Up @@ -366,12 +366,10 @@ public String toString() {
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();
Expand Down
77 changes: 52 additions & 25 deletions src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
Expand Up @@ -30,6 +30,9 @@

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;
Expand Down Expand Up @@ -124,33 +127,57 @@ private void invokeImpl(boolean wait, Runnable task, boolean stop) {
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);
}
}
}
Expand All @@ -161,7 +188,7 @@ final public void waitUntilIdle() {
synchronized(edtLock) {
_edt = nedt;
}
if(!_edt.isRunning() || EventQueue.isDispatchThread() || _edt == Thread.currentThread()) {
if(!_edt.isRunning() || _edt == Thread.currentThread() || EventQueue.isDispatchThread()) {
return;
}
try {
Expand All @@ -174,7 +201,7 @@ public void run() { }
@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();
Expand Down

0 comments on commit 17dd761

Please sign in to comment.