diff options
author | Sven Gothel <[email protected]> | 2010-04-13 20:48:50 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-04-13 20:48:50 +0200 |
commit | 1c1053c6a8b669c067ae1316b9770871e213ea05 (patch) | |
tree | af4ed7ea0b41ea6626cc0ad2208b495733b4056e /src/newt/classes | |
parent | 98de1d96e77a1c1aad237a8e5c6c63e21bcb5fc2 (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')
-rwxr-xr-x | src/newt/classes/com/jogamp/newt/Display.java | 47 | ||||
-rwxr-xr-x | src/newt/classes/com/jogamp/newt/Window.java | 63 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/opengl/GLWindow.java | 6 | ||||
-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) { |