summaryrefslogtreecommitdiffstats
path: root/src/newt/classes/com/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-04-13 20:48:50 +0200
committerSven Gothel <[email protected]>2010-04-13 20:48:50 +0200
commit1c1053c6a8b669c067ae1316b9770871e213ea05 (patch)
treeaf4ed7ea0b41ea6626cc0ad2208b495733b4056e /src/newt/classes/com/jogamp
parent98de1d96e77a1c1aad237a8e5c6c63e21bcb5fc2 (diff)
NEWT X11 Fix (mainly ATI and multithreading)
- EventDispatchThread -> EDTUtil Since the name leads to the assumptions that an instance is the EDT. EDTUtil manages the EDT within. - EDTUtil, no more reference to Display, but use a Runnable for the pumpMessage() - Window.destroy() check if already done - X11Window: Added XErrorHandler to catch BadWindow and BadAtom while dispatching events - it is possible that the resource is already freed. Also added an XIOErrorHandler to identify the fatal Display* inaccessibility. Tests: - New junit/com/jogamp/test/junit/newt/TestWindows01NEWT.java Testing creation/destruction and double destruction (error case) - Fix: src/junit/com/jogamp/test/junit/jogl/offscreen/TestOffscreen01NEWT.java Properly holding all NEWT references .. Misc: - Reduced redundant NEWT 'toString()' output (*Capabilities, ..) -
Diffstat (limited to 'src/newt/classes/com/jogamp')
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/Display.java47
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/Window.java63
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java6
-rw-r--r--src/newt/classes/com/jogamp/newt/util/EDTUtil.java (renamed from src/newt/classes/com/jogamp/newt/util/EventDispatchThread.java)92
4 files changed, 110 insertions, 98 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index 88f6dd34b..2bc99475c 100755
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -35,7 +35,7 @@ package com.jogamp.newt;
import javax.media.nativewindow.*;
import com.jogamp.newt.impl.Debug;
-import com.jogamp.newt.util.EventDispatchThread;
+import com.jogamp.newt.util.EDTUtil;
import java.util.*;
public abstract class Display {
@@ -141,11 +141,16 @@ public abstract class Display {
display.refCount=1;
if(NewtFactory.useEDT()) {
- Thread current = Thread.currentThread();
- display.eventDispatchThread = new EventDispatchThread(display, current.getThreadGroup(), current.getName());
- display.eventDispatchThread.start();
final Display f_dpy = display;
- display.eventDispatchThread.invokeAndWait(new Runnable() {
+ Thread current = Thread.currentThread();
+ display.edtUtil = new EDTUtil(current.getThreadGroup(),
+ "Display_"+display.getName()+"-"+current.getName(),
+ new Runnable() {
+ public void run() {
+ f_dpy.pumpMessagesImpl();
+ } } );
+ display.edt = display.edtUtil.start();
+ display.edtUtil.invokeAndWait(new Runnable() {
public void run() {
f_dpy.createNative();
}
@@ -189,7 +194,7 @@ public abstract class Display {
}
}
- public EventDispatchThread getEDT() { return eventDispatchThread; }
+ public EDTUtil getEDTUtil() { return edtUtil; }
public synchronized void destroy() {
if(DEBUG) {
@@ -201,10 +206,10 @@ public abstract class Display {
if(DEBUG) {
System.err.println("Display.destroy("+name+") REMOVE: "+this+" "+Thread.currentThread());
}
- if(null!=eventDispatchThread) {
+ if(null!=edtUtil) {
final Display f_dpy = this;
- final EventDispatchThread f_edt = eventDispatchThread;
- eventDispatchThread.invokeAndWait(new Runnable() {
+ final EDTUtil f_edt = edtUtil;
+ edtUtil.invokeAndWait(new Runnable() {
public void run() {
f_dpy.closeNative();
f_edt.stop();
@@ -213,9 +218,9 @@ public abstract class Display {
} else {
closeNative();
}
- if(null!=eventDispatchThread) {
- eventDispatchThread.waitUntilStopped();
- eventDispatchThread=null;
+ if(null!=edtUtil) {
+ edtUtil.waitUntilStopped();
+ edtUtil=null;
}
aDevice = null;
} else {
@@ -246,14 +251,13 @@ public abstract class Display {
return aDevice;
}
- public void pumpMessages() {
- if(null!=eventDispatchThread) {
- dispatchMessages();
- } else {
- synchronized(this) {
- dispatchMessages();
- }
- }
+ public synchronized void pumpMessages() {
+ pumpMessagesImpl();
+ }
+
+ private void pumpMessagesImpl() {
+ if(0==refCount) return;
+ dispatchMessages();
}
public String toString() {
@@ -268,7 +272,8 @@ public abstract class Display {
/** Default impl. nop - Currently only X11 needs a Display lock */
protected void unlockDisplay() { }
- protected EventDispatchThread eventDispatchThread = null;
+ protected EDTUtil edtUtil = null;
+ protected Thread edt = null;
protected String name;
protected int refCount;
protected AbstractGraphicsDevice aDevice;
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 171bb2468..8f09ae364 100755
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -34,7 +34,7 @@
package com.jogamp.newt;
import com.jogamp.newt.impl.Debug;
-import com.jogamp.newt.util.EventDispatchThread;
+import com.jogamp.newt.util.EDTUtil;
import javax.media.nativewindow.*;
import com.jogamp.nativewindow.impl.NWReflection;
@@ -98,10 +98,10 @@ public abstract class Window implements NativeWindow
window.invalidate();
window.screen = screen;
window.setUndecorated(undecorated||0!=parentWindowHandle);
- EventDispatchThread edt = screen.getDisplay().getEDT();
- if(null!=edt) {
+ EDTUtil edtUtil = screen.getDisplay().getEDTUtil();
+ if(null!=edtUtil) {
final Window f_win = window;
- edt.invokeAndWait(new Runnable() {
+ edtUtil.invokeAndWait(new Runnable() {
public void run() {
f_win.createNative(parentWindowHandle, caps);
}
@@ -131,10 +131,10 @@ public abstract class Window implements NativeWindow
window.invalidate();
window.screen = screen;
window.setUndecorated(undecorated);
- EventDispatchThread edt = screen.getDisplay().getEDT();
- if(null!=edt) {
+ EDTUtil edtUtil = screen.getDisplay().getEDTUtil();
+ if(null!=edtUtil) {
final Window f_win = window;
- edt.invokeAndWait(new Runnable() {
+ edtUtil.invokeAndWait(new Runnable() {
public void run() {
f_win.createNative(0, caps);
}
@@ -212,15 +212,15 @@ public abstract class Window implements NativeWindow
public String toString() {
StringBuffer sb = new StringBuffer();
- sb.append(getClass().getName()+"[config "+config+
- ", windowHandle "+toHexString(getWindowHandle())+
- ", surfaceHandle "+toHexString(getSurfaceHandle())+
- ", pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
- ", visible "+isVisible()+
- ", undecorated "+undecorated+
- ", fullscreen "+fullscreen+
+ sb.append(getClass().getName()+"[Config "+config+
+ ", WindowHandle "+toHexString(getWindowHandle())+
+ ", SurfaceHandle "+toHexString(getSurfaceHandle())+
+ ", Pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
+ ", Visible "+isVisible()+
+ ", Undecorated "+undecorated+
+ ", Fullscreen "+fullscreen+
", "+screen+
- ", wrappedWindow "+getWrappedWindow());
+ ", WrappedWindow "+getWrappedWindow());
sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedListeners.size()+" [");
for (Iterator iter = surfaceUpdatedListeners.iterator(); iter.hasNext(); ) {
@@ -343,25 +343,28 @@ public abstract class Window implements NativeWindow
keyListeners = new ArrayList();
}
synchronized(this) {
- destructionLock.lock();
try {
- Screen scr = screen;
- Display dpy = (null!=screen) ? screen.getDisplay() : null;
- EventDispatchThread edt = (null!=dpy) ? dpy.getEDT() : null;
- if(null!=edt) {
- final Window f_win = this;
- edt.invokeAndWait(new Runnable() {
- public void run() {
- f_win.closeNative();
- }
- } );
- } else {
- closeNative();
+ destructionLock.lock();
+ Display dpy = null;
+ if( null != screen && 0 != windowHandle ) {
+ Screen scr = screen;
+ dpy = (null!=screen) ? screen.getDisplay() : null;
+ EDTUtil edtUtil = (null!=dpy) ? dpy.getEDTUtil() : null;
+ if(null!=edtUtil) {
+ final Window f_win = this;
+ edtUtil.invokeAndWait(new Runnable() {
+ public void run() {
+ f_win.closeNative();
+ }
+ } );
+ } else {
+ closeNative();
+ }
}
invalidate();
if(deep) {
- if(null!=scr) {
- scr.destroy();
+ if(null!=screen) {
+ screen.destroy();
}
if(null!=dpy) {
dpy.destroy();
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 4a7f27f3a..fec70c99c 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -65,7 +65,7 @@ public class GLWindow extends Window implements GLAutoDrawable {
this.ownerOfWinScrDpy = ownerOfWinScrDpy;
this.window = window;
this.window.setAutoDrawableClient(true);
- this.runPumpMessages = ( null == getScreen().getDisplay().getEDT() ) ;
+ this.runPumpMessages = ( null == getScreen().getDisplay().getEDTUtil() ) ;
window.addWindowListener(new WindowListener() {
public void windowResized(WindowEvent e) {
sendReshape = true;
@@ -152,7 +152,7 @@ public class GLWindow extends Window implements GLAutoDrawable {
* @deprecated EXPERIMENTAL, semantic is about to be removed after further verification.
*/
public void setRunPumpMessages(boolean onoff) {
- if( onoff && null!=getScreen().getDisplay().getEDT() ) {
+ if( onoff && null!=getScreen().getDisplay().getEDTUtil() ) {
throw new GLException("GLWindow.setRunPumpMessages(true) - Can't do with EDT on");
}
runPumpMessages = onoff;
@@ -382,7 +382,7 @@ public class GLWindow extends Window implements GLAutoDrawable {
}
public String toString() {
- return "NEWT-GLWindow[ \n\tDrawable: "+drawable+", \n\tWindow: "+window+", \n\tHelper: "+helper+", \n\tFactory: "+factory+"]";
+ return "NEWT-GLWindow[ \n\tHelper: "+helper+", \n\tDrawable: "+drawable + /** ", \n\tWindow: "+window+", \n\tFactory: "+factory+ */ "]";
}
//----------------------------------------------------------------------
diff --git a/src/newt/classes/com/jogamp/newt/util/EventDispatchThread.java b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
index 675c6f322..f852bcf5c 100644
--- a/src/newt/classes/com/jogamp/newt/util/EventDispatchThread.java
+++ b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
@@ -40,30 +40,30 @@ import com.jogamp.newt.Display;
import com.jogamp.newt.impl.Debug;
import java.util.*;
-public class EventDispatchThread {
+public class EDTUtil {
public static final boolean DEBUG = Debug.debug("EDT");
private ThreadGroup threadGroup;
private volatile boolean shouldStop = false;
- private TaskWorker taskWorker = null;
- private Object taskWorkerLock = new Object();
+ private EventDispatchThread edt = null;
+ private Object edtLock = new Object();
private ArrayList tasks = new ArrayList(); // one shot tasks
- private Display display = null;
private String name;
- private long edtPollGranularity = 10;
+ private Runnable pumpMessages;
+ private long edtPollGranularity = 10; // 10ms, 1/100s
- public EventDispatchThread(Display display, ThreadGroup tg, String name) {
- this.display = display;
+ public EDTUtil(ThreadGroup tg, String name, Runnable pumpMessages) {
this.threadGroup = tg;
- this.name=new String("EDT-Display_"+display.getName()+"-"+name);
+ this.name=new String("EDT-"+name);
+ this.pumpMessages=pumpMessages;
}
public String getName() { return name; }
public ThreadGroup getThreadGroup() { return threadGroup; }
- public void start() {
- start(false);
+ public Thread start() {
+ return start(false);
}
/**
@@ -75,52 +75,56 @@ public class EventDispatchThread {
* Usefull in combination with externalStimuli=true,
* so an external stimuli can call it.
*/
- public Runnable start(boolean externalStimuli) {
- synchronized(taskWorkerLock) {
- if(null==taskWorker) {
- taskWorker = new TaskWorker(threadGroup, name);
+ public Thread start(boolean externalStimuli) {
+ synchronized(edtLock) {
+ if(null==edt) {
+ edt = new EventDispatchThread(threadGroup, name);
}
- if(!taskWorker.isRunning()) {
+ if(!edt.isRunning()) {
shouldStop = false;
- taskWorker.start(externalStimuli);
+ edt.start(externalStimuli);
}
- taskWorkerLock.notifyAll();
+ edtLock.notifyAll();
}
- return taskWorker;
+ return edt;
}
public void stop() {
- synchronized(taskWorkerLock) {
- if(null!=taskWorker && taskWorker.isRunning()) {
+ synchronized(edtLock) {
+ if(null!=edt && edt.isRunning()) {
shouldStop = true;
}
- taskWorkerLock.notifyAll();
+ edtLock.notifyAll();
if(DEBUG) {
System.out.println(Thread.currentThread()+": EDT signal STOP");
}
}
}
+ public Thread getEDT() {
+ return edt;
+ }
+
public boolean isThreadEDT(Thread thread) {
- return null!=taskWorker && taskWorker == thread;
+ return null!=edt && edt == thread;
}
public boolean isCurrentThreadEDT() {
- return null!=taskWorker && taskWorker == Thread.currentThread();
+ return null!=edt && edt == Thread.currentThread();
}
public boolean isRunning() {
- return null!=taskWorker && taskWorker.isRunning() ;
+ return null!=edt && edt.isRunning() ;
}
public void invokeLater(Runnable task) {
if(task == null) {
return;
}
- synchronized(taskWorkerLock) {
- if(null!=taskWorker && taskWorker.isRunning() && taskWorker != Thread.currentThread() ) {
+ synchronized(edtLock) {
+ if(null!=edt && edt.isRunning() && edt != Thread.currentThread() ) {
tasks.add(task);
- taskWorkerLock.notifyAll();
+ edtLock.notifyAll();
} else {
// if !running or isEDTThread, do it right away
task.run();
@@ -137,10 +141,10 @@ public class EventDispatchThread {
}
public void waitOnWorker() {
- synchronized(taskWorkerLock) {
- if(null!=taskWorker && taskWorker.isRunning() && tasks.size()>0 && taskWorker != Thread.currentThread() ) {
+ synchronized(edtLock) {
+ if(null!=edt && edt.isRunning() && tasks.size()>0 && edt != Thread.currentThread() ) {
try {
- taskWorkerLock.wait();
+ edtLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
@@ -149,10 +153,10 @@ public class EventDispatchThread {
}
public void waitUntilStopped() {
- synchronized(taskWorkerLock) {
- while(null!=taskWorker && taskWorker.isRunning() && taskWorker != Thread.currentThread() ) {
+ synchronized(edtLock) {
+ while(null!=edt && edt.isRunning() && edt != Thread.currentThread() ) {
try {
- taskWorkerLock.wait();
+ edtLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
@@ -160,11 +164,11 @@ public class EventDispatchThread {
}
}
- class TaskWorker extends Thread {
+ class EventDispatchThread extends Thread {
boolean isRunning = false;
boolean externalStimuli = false;
- public TaskWorker(ThreadGroup tg, String name) {
+ public EventDispatchThread(ThreadGroup tg, String name) {
super(tg, name);
}
@@ -183,7 +187,7 @@ public class EventDispatchThread {
}
/**
- * Utilizing taskWorkerLock only for local resources and task execution,
+ * Utilizing edtLock only for local resources and task execution,
* not for event dispatching.
*/
public void run() {
@@ -194,26 +198,26 @@ public class EventDispatchThread {
try {
// wait for something todo
while(!shouldStop && tasks.size()==0) {
- synchronized(taskWorkerLock) {
+ synchronized(edtLock) {
if(!shouldStop && tasks.size()==0) {
try {
- taskWorkerLock.wait(edtPollGranularity);
+ edtLock.wait(edtPollGranularity);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- display.pumpMessages(); // event dispatch
+ pumpMessages.run(); // event dispatch
}
if(!shouldStop && tasks.size()>0) {
- synchronized(taskWorkerLock) {
+ synchronized(edtLock) {
if(!shouldStop && tasks.size()>0) {
Runnable task = (Runnable) tasks.remove(0);
task.run();
- taskWorkerLock.notifyAll();
+ edtLock.notifyAll();
}
}
- display.pumpMessages(); // event dispatch
+ pumpMessages.run(); // event dispatch
}
} catch (Throwable t) {
// handle errors ..
@@ -227,8 +231,8 @@ public class EventDispatchThread {
isRunning = !shouldStop;
}
if(!isRunning) {
- synchronized(taskWorkerLock) {
- taskWorkerLock.notifyAll();
+ synchronized(edtLock) {
+ edtLock.notifyAll();
}
}
if(DEBUG) {