summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-09-27 12:51:47 +0200
committerSven Gothel <[email protected]>2011-09-27 12:51:47 +0200
commitfa35bd758189051dc25b8a0d32dc52360cfbc390 (patch)
treec7e500cbf247933aab419caccc9e279a79ddf82b
parent472a9c60b5599bb01883c628339ab29628511ed5 (diff)
NEWT/Threading: MainThread / DefaultEDTUtil
- MainThread: This class no more implements EDTUtil! This class just provides a main-thread utility, forking of a main java class on another thread while being able to continue doing platform specific things on the main-thread. The latter is essential for eg. MacOSX, where we continue to run NSApp.run(). - DefaultEDTUtil: - if Lock.DEBUG validate that no recursive locks are being hold, where it shall not (EDT: startup and return from task execution) - If task execution's result wasn't waited for (checked), at least dump exeception's stack trace if i happened. - MacDisplay: Just use DefaultEDTUtil - MacWindow: - No more need of special locking -> removed nsViewLock, since: - using proper EDT - capability to run from multiple threads (native Java thread attachment)
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MainThread.java87
-rw-r--r--src/newt/classes/jogamp/newt/DefaultEDTUtil.java20
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java29
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java33
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java149
5 files changed, 94 insertions, 224 deletions
diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java
index f74845afc..8de77420f 100644
--- a/src/newt/classes/com/jogamp/newt/util/MainThread.java
+++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java
@@ -41,23 +41,26 @@ import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessControlContext;
import java.security.AccessController;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
import javax.media.nativewindow.NativeWindowFactory;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.newt.Display;
import jogamp.newt.Debug;
-import jogamp.newt.DefaultEDTUtil;
import jogamp.newt.NEWTJNILibLoader;
/**
* NEWT Utility class MainThread<P>
*
+ * <p>
+ * FIXME: Update this documentation!
+ * This class just provides a main-thread utility, forking of a main java class
+ * on another thread while being able to continue doing platform specific things
+ * on the main-thread. The latter is essential for eg. MacOSX, where we continue
+ * to run NSApp.run().
+ * </p>
+ *
* This class provides a startup singleton <i>main thread</i>,
* from which a new thread with the users main class is launched.<br>
*
@@ -88,7 +91,7 @@ import jogamp.newt.NEWTJNILibLoader;
</PRE>
* Which starts 4 threads, each with a window and OpenGL rendering.<br>
*/
-public class MainThread implements EDTUtil {
+public class MainThread {
private static final String MACOSXDisplayClassName = "jogamp.newt.driver.macosx.MacDisplay";
/** if true, use the main thread EDT, otherwise AWT's EDT */
@@ -109,8 +112,6 @@ public class MainThread implements EDTUtil {
private static final MainThread singletonMainThread = new MainThread(); // one singleton MainThread
- private static final Map<Display, Runnable> pumpMessageDisplayMap = new HashMap<Display, Runnable>();
-
static class MainAction extends Thread {
private String mainClassName;
private String[] mainClassArgs;
@@ -148,10 +149,6 @@ public class MainThread implements EDTUtil {
if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" user app fin");
if ( useMainThread ) {
- singletonMainThread.invokeStop(new Runnable() {
- public void run() {
- // nop
- }});
if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" MainThread fin - stop");
System.exit(0);
}
@@ -159,8 +156,6 @@ public class MainThread implements EDTUtil {
}
private static MainAction mainAction;
- private static EDTUtil internalEDT;
-
/** Your new java application main entry, which pipelines your application */
public static void main(String[] args) {
useMainThread = HINT_USE_MAIN_THREAD;
@@ -197,26 +192,21 @@ public class MainThread implements EDTUtil {
}
if ( useMainThread ) {
- final Thread current = Thread.currentThread();
- internalEDT = new DefaultEDTUtil(current.getThreadGroup(), "MainThread", new Runnable() {
- public void run() { dispatchMessages(); } });
-
- if(DEBUG) System.err.println("MainThread - run: "+internalEDT.toString());
- internalEDT.start(); // forever !
-
// dispatch user's main thread ..
mainAction.start();
if(isMacOSX) {
try {
- if(DEBUG) System.err.println("MainThread - runNSApp");
+ if(DEBUG) {
+ System.err.println("MainThread.main(): "+Thread.currentThread().getName()+"- runNSApp");
+ }
ReflectionUtil.callStaticMethod(MACOSXDisplayClassName, "runNSApplication",
null, null, MainThread.class.getClassLoader());
} catch (Exception e) {
e.printStackTrace();
}
}
- if(DEBUG) System.err.println("MainThread - wait until last non daemon thread ends ...");
+ if(DEBUG) { System.err.println("MainThread - wait until last non daemon thread ends ..."); }
} else {
// run user's main in this thread
mainAction.run();
@@ -227,57 +217,6 @@ public class MainThread implements EDTUtil {
return singletonMainThread;
}
- public static Runnable removePumpMessage(Display dpy) {
- synchronized(pumpMessageDisplayMap) {
- return pumpMessageDisplayMap.remove(dpy);
- }
- }
-
- public static void addPumpMessage(Display dpy, Runnable pumpMessage) {
- synchronized (pumpMessageDisplayMap) {
- pumpMessageDisplayMap.put(dpy, pumpMessage);
- }
- }
-
- private static void dispatchMessages() {
- synchronized(pumpMessageDisplayMap) {
- for(Iterator<Runnable> i = pumpMessageDisplayMap.values().iterator(); i.hasNext(); ) {
- i.next().run();
- }
- }
- }
-
- final public void reset() {
- // nop: ALWAYS RUNNING
- }
-
- final public void start() {
- // nop: ALWAYS RUNNING
- }
-
- final public boolean isCurrentThreadEDT() {
- return internalEDT.isCurrentThreadEDT();
- }
-
- final public boolean isRunning() {
- return true; // ALWAYS RUNNING
- }
-
- final public void invokeStop(Runnable r) {
- internalEDT.invoke(true, r); // ALWAYS RUNNING
- }
-
- final public void invoke(boolean wait, Runnable r) {
- internalEDT.invoke(wait, r);
- }
-
- final public void waitUntilIdle() {
- internalEDT.waitUntilIdle();
- }
-
- final public void waitUntilStopped() {
- // nop: ALWAYS RUNNING
- }
}
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
index 3e8715364..0bcd3323c 100644
--- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
@@ -39,7 +39,11 @@ package jogamp.newt;
import java.util.ArrayList;
import javax.media.nativewindow.NativeWindowException;
+
+import jogamp.common.util.locks.LockDebugUtil;
+
import com.jogamp.common.util.RunnableTask;
+import com.jogamp.common.util.locks.Lock;
import com.jogamp.newt.util.EDTUtil;
public class DefaultEDTUtil implements EDTUtil {
@@ -235,6 +239,15 @@ public class DefaultEDTUtil implements EDTUtil {
super.start();
}
+ private final void validateNoRecursiveLocksHold() {
+ if(Lock.DEBUG) {
+ if(LockDebugUtil.getRecursiveLockTrace().size()>0) {
+ LockDebugUtil.dumpRecursiveLockTrace(System.err);
+ throw new InternalError("XXX");
+ }
+ }
+ }
+
/**
* Utilizing locking only on tasks and its execution,
* not for event dispatching.
@@ -244,6 +257,7 @@ public class DefaultEDTUtil implements EDTUtil {
if(DEBUG) {
System.err.println(getName()+": EDT run() START "+ getName());
}
+ validateNoRecursiveLocksHold();
RuntimeException error = null;
try {
do {
@@ -269,8 +283,12 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
if(null!=task) {
- // Exceptions are always catched, see RunnableTask creation above
task.run();
+ validateNoRecursiveLocksHold();
+ if(!task.hasWaiter() && null != task.getThrowable()) {
+ // at least dump stack-trace in case nobody waits for result
+ task.getThrowable().printStackTrace();
+ }
}
} while(!shouldStop) ;
} catch (Throwable t) {
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index ee370029e..cfe9f0c2d 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -39,18 +39,14 @@ import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.event.NEWTEvent;
import com.jogamp.newt.event.NEWTEventConsumer;
-import jogamp.newt.driver.awt.AWTEDTUtil;
import jogamp.newt.event.NEWTEventTask;
import com.jogamp.newt.util.EDTUtil;
-import com.jogamp.newt.util.MainThread;
import java.util.ArrayList;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.NativeWindowFactory;
public abstract class DisplayImpl extends Display {
- public static final boolean DEBUG_TEST_EDT_MAINTHREAD = Debug.isPropertyDefined("newt.test.EDTMainThread", true); // JAU EDT Test ..
-
private static int serialno = 1;
private static Class<?> getDisplayClass(String type)
@@ -171,27 +167,7 @@ public abstract class DisplayImpl extends Display {
protected void createEDTUtil() {
if(NewtFactory.useEDT()) {
- if ( ! DEBUG_TEST_EDT_MAINTHREAD ) {
- final Thread current = Thread.currentThread();
- edtUtil = new DefaultEDTUtil(current.getThreadGroup(), "Display-"+getFQName(), dispatchMessagesRunnable);
- } else {
- // Begin JAU EDT Test ..
- final Display f_dpy = this;
- final Runnable dispatchRunner = new Runnable() {
- public void run() {
- if(null!=f_dpy.getGraphicsDevice()) {
- f_dpy.dispatchMessages();
- } } };
-
- if(NativeWindowFactory.isAWTAvailable()) {
- AWTEDTUtil.addPumpMessage(this, dispatchRunner);
- edtUtil = AWTEDTUtil.getSingleton();
- } else {
- MainThread.addPumpMessage(this, dispatchRunner);
- edtUtil = MainThread.getSingleton();
- }
- // End JAU EDT Test ..
- }
+ edtUtil = new DefaultEDTUtil(Thread.currentThread().getThreadGroup(), "Display-"+getFQName(), dispatchMessagesRunnable);
if(DEBUG) {
System.err.println("Display.createNative("+getFQName()+") Create EDTUtil: "+edtUtil.getClass().getName());
}
@@ -255,9 +231,6 @@ public abstract class DisplayImpl extends Display {
}
} );
if(null!=edtUtil) {
- if ( DEBUG_TEST_EDT_MAINTHREAD ) {
- MainThread.removePumpMessage(this); // JAU EDT Test ..
- }
edtUtil.waitUntilStopped();
edtUtil.reset();
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java b/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
index 572d37efe..527fdac6d 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
@@ -35,11 +35,7 @@ package jogamp.newt.driver.macosx;
import javax.media.nativewindow.*;
import javax.media.nativewindow.macosx.*;
-import com.jogamp.newt.*;
import jogamp.newt.*;
-import jogamp.newt.driver.awt.AWTEDTUtil;
-
-import com.jogamp.newt.util.MainThread;
public class MacDisplay extends DisplayImpl {
static {
@@ -73,35 +69,6 @@ public class MacDisplay extends DisplayImpl {
protected void closeNativeImpl() { }
- /**
- @Override
- protected void createEDTUtil() {
- if(NewtFactory.useEDT()) {
- final Display f_dpy = this;
- final Runnable dispatchRunner = new Runnable() {
- public void run() {
- if(null!=f_dpy.getGraphicsDevice()) {
- f_dpy.dispatchMessages();
- } } };
-
- if(NativeWindowFactory.isAWTAvailable()) {
- AWTEDTUtil.addPumpMessage(this, dispatchRunner);
- edtUtil = AWTEDTUtil.getSingleton();
- } else {
- MainThread.addPumpMessage(this, dispatchRunner);
- edtUtil = MainThread.getSingleton();
- }
- }
- } */
-
- protected void releaseEDTUtil() {
- if(null!=edtUtil) {
- MainThread.removePumpMessage(this);
- edtUtil.waitUntilStopped();
- edtUtil=null;
- }
- }
-
public static void runNSApplication() {
runNSApplication0();
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
index 3265da1c1..8fe32029c 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
@@ -36,8 +36,6 @@ package jogamp.newt.driver.macosx;
import javax.media.nativewindow.*;
-import com.jogamp.common.util.locks.RecursiveLock;
-
import com.jogamp.newt.event.*;
import jogamp.nativewindow.macosx.OSXUtil;
@@ -157,7 +155,6 @@ public class MacWindow extends WindowImpl {
}
protected void closeNativeImpl() {
- nsViewLock.lock();
try {
if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.CloseAction "+Thread.currentThread().getName()); }
if (getWindowHandle() != 0) {
@@ -171,7 +168,6 @@ public class MacWindow extends WindowImpl {
}
} finally {
setWindowHandle(0);
- nsViewLock.unlock();
}
}
@@ -180,105 +176,82 @@ public class MacWindow extends WindowImpl {
return surfaceHandle;
}
- private RecursiveLock nsViewLock = new RecursiveLock();
-
- @Override
- protected int lockSurfaceImpl() {
- nsViewLock.lock();
- return LOCK_SUCCESS;
- }
-
- @Override
- protected void unlockSurfaceImpl() {
- nsViewLock.unlock();
- }
-
@Override
protected void setTitleImpl(final String title) {
- // FIXME: move nsViewLock up to window lock
- nsViewLock.lock();
- try {
- setTitle0(getWindowHandle(), title);
- } finally {
- nsViewLock.unlock();
- }
+ setTitle0(getWindowHandle(), title);
}
protected void requestFocusImpl(boolean reparented) {
- // FIXME: move nsViewLock up to window lock
- nsViewLock.lock();
- try {
- makeKeyAndOrderFront0(getWindowHandle());
- // makeKey0(getWindowHandle());
- } finally {
- nsViewLock.unlock();
- }
+ makeKeyAndOrderFront0(getWindowHandle());
}
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
- nsViewLock.lock();
- try {
- int _x = x, _y = y;
- if(0 == ( FLAG_IS_UNDECORATED & flags) && 0<=_x && 0<=_y) {
- final InsetsImmutable i = getInsets();
-
- // client position -> top-level window position
- _x -= i.getLeftWidth() ;
- _y -= i.getTopHeight() ;
- if( 0 > _x ) { _x = 0; }
- if( 0 > _y ) { _y = 0; }
- }
+ int _x = x, _y = y;
+ if(0 == ( FLAG_IS_UNDECORATED & flags) && 0<=_x && 0<=_y) {
+ final InsetsImmutable i = getInsets();
+
+ // client position -> top-level window position
+ _x -= i.getLeftWidth() ;
+ _y -= i.getTopHeight() ;
+ if( 0 > _x ) { _x = 0; }
+ if( 0 > _y ) { _y = 0; }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow reconfig (insets: "+i+"): "+x+"/"+y+" -> "+_x+"/"+_y);
+ }
+ }
+ {
final NativeWindow parent = getParent();
if(null != parent) {
final Point p = parent.getLocationOnScreen(null);
_x += p.getX();
_y += p.getY();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow reconfig (parent abs pos: "+p+"): "+x+"/"+y+" -> "+_x+"/"+_y);
+ }
}
-
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+_x+"/"+_y+" - "+width+"x"+height+", "+
- getReconfigureFlagsAsString(null, flags));
- }
-
- if( getWindowHandle() == 0 ) {
+ }
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+_x+"/"+_y+" - "+width+"x"+height+", "+
+ getReconfigureFlagsAsString(null, flags));
+ }
+
+ if( getWindowHandle() == 0 ) {
+ if( 0 != ( FLAG_IS_VISIBLE & flags) ) {
+ createWindow(false, _x, _y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+ this.x = x;
+ this.y = y;
+ visibleChanged(false, true); // no native event ..
+ } /* else { ?? } */
+ } else {
+ if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
if( 0 != ( FLAG_IS_VISIBLE & flags) ) {
- createWindow(false, _x, _y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
- this.x = x;
- this.y = y;
- visibleChanged(true); // no native event ..
- } /* else { ?? } */
- } else {
- if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
- if( 0 != ( FLAG_IS_VISIBLE & flags) ) {
- makeKeyAndOrderFront0(getWindowHandle());
- visibleChanged(true); // no native event ..
- enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
- } else {
- orderOut0(getWindowHandle());
- visibleChanged(false); // no native event ..
- enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_LOST_FOCUS);
- }
- } else if( 0 != ( FLAG_CHANGE_DECORATION & flags) ||
- 0 != ( FLAG_CHANGE_PARENTING & flags) ||
- 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
- createWindow(true, x, y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
- }
- if(x>=0 || y>=0) {
- setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), _x, _y);
- this.x = x;
- this.y = y;
- enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_MOVED);
+ makeKeyAndOrderFront0(getWindowHandle());
+ visibleChanged(false, true); // no native event ..
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
+ } else {
+ orderOut0(getWindowHandle());
+ visibleChanged(false, false); // no native event ..
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_LOST_FOCUS);
}
- if(width>0 || height>0) {
- setContentSize0(getWindowHandle(), width, height);
- this.width = width;
- this.height = height;
- enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_RESIZED);
- }
- setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags));
+ } else if( 0 != ( FLAG_CHANGE_DECORATION & flags) ||
+ 0 != ( FLAG_CHANGE_PARENTING & flags) ||
+ 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
+ createWindow(true, x, y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
}
- } finally {
- nsViewLock.unlock();
+ if(x>=0 && y>=0) {
+ setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), _x, _y);
+ this.x = x;
+ this.y = y;
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_MOVED);
+ }
+ if(width>0 && height>0) {
+ setContentSize0(getWindowHandle(), width, height);
+ this.width = width;
+ this.height = height;
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_RESIZED);
+ }
+ setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags));
}
return true;
}
@@ -437,14 +410,14 @@ public class MacWindow extends WindowImpl {
}
@Override
- protected void positionChanged(int newX, int newY) {
+ protected void positionChanged(boolean defer, int newX, int newY) {
final NativeWindow parent = getParent();
if(null != parent) {
final Point p = parent.getLocationOnScreen(null);
newX -= p.getX();
newY -= p.getY();
}
- super.positionChanged(newX, newY);
+ super.positionChanged(defer, newX, newY);
}
protected static native boolean initIDs0();