diff options
author | Sven Gothel <[email protected]> | 2013-11-29 02:24:01 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-11-29 02:24:01 +0100 |
commit | 586446311ea1ba87f98236d5347955bf99b465d6 (patch) | |
tree | 2bba93f117ec08bbb3ea96ee6cd2c44d97b04421 /src/nativewindow/classes | |
parent | cb0afe743d21a3480e2d41744a904ac7d404612d (diff) |
Bug 907 - Refine DummyDispatchThread (DDT) Handling: Proper OO integration in RegisteredClass; Safe DDT Post/WaitForReady handling and error cases ; ...
Proper OO integration of DDT in RegisteredClass
- DDT is optional to RegisteredClass[Factory],
i.e. NEWT without DDT and DummyWindow with DDT.
- Using native type DummyThreadContext per DDT
passed as DDT handle to java referenced in RegisteredClass
- Passing DDT handle to related native methods,
if not null use DDT - otherwise work on current thread.
The latter impacts CreateDummyWindow0 and DestroyWindow0.
Safe DDT Post/WaitForReady handling and error cases ; ...
- Wait until command it complete using a 3s timeout
- Terminate thread if errors occur and throw an exception
+++
Discussion: DDT Native Implementation
Due to original code, the DDT is implemented in native code.
Usually we should favor running the DDT from a java thread.
However, since it's main purpose is _not_ to interact w/ java
and the native implementation has less footprint (performance and memory)
we shall be OK w/ it for now - as long the implementation IS SAFE.
Diffstat (limited to 'src/nativewindow/classes')
3 files changed, 44 insertions, 24 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java index bab4b5c6e..a872e63d8 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java @@ -59,7 +59,7 @@ public class GDIUtil implements ToolkitProperties { if( !initIDs0() ) { throw new NativeWindowException("GDI: Could not initialized native stub"); } - dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0()); + dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0(), true /* useDummyDispatchThread */); if(DEBUG) { System.out.println("GDI.initSingleton() dummyWindowClassFactory "+dummyWindowClassFactory); } @@ -98,8 +98,7 @@ public class GDIUtil implements ToolkitProperties { System.out.println("GDI.CreateDummyWindow() dummyWindowClassFactory "+dummyWindowClassFactory); System.out.println("GDI.CreateDummyWindow() dummyWindowClass "+dummyWindowClass); } - // FIXME return CreateDummyWindow0(dummyWindowClass.getHInstance(), dummyWindowClass.getName(), dummyWindowClass.getName(), x, y, width, height); - return CreateDummyWindowAndMessageLoop(dummyWindowClass.getHInstance(), dummyWindowClass.getName(), dummyWindowClass.getName(), x, y, width, height); + return CreateDummyWindow0(dummyWindowClass.getHInstance(), dummyWindowClass.getName(), dummyWindowClass.getHDispThreadContext(), dummyWindowClass.getName(), x, y, width, height); } } @@ -109,8 +108,7 @@ public class GDIUtil implements ToolkitProperties { if( null == dummyWindowClass ) { throw new InternalError("GDI Error ("+dummyWindowClassFactory.getSharedRefCount()+"): SharedClass is null"); } - // FIXME res = GDI.DestroyWindow(hwnd); - res = SendCloseMessage(hwnd); + res = DestroyWindow0(dummyWindowClass.getHDispThreadContext(), hwnd); dummyWindowClassFactory.releaseSharedClass(); } return res; @@ -128,8 +126,11 @@ public class GDIUtil implements ToolkitProperties { return IsChild0(win); } - public static native boolean CreateWindowClass(long hInstance, String clazzName, long wndProc); - public static native boolean DestroyWindowClass(long hInstance, String className); + private static final void dumpStack() { Thread.dumpStack(); } // Callback for JNI + + static native boolean CreateWindowClass0(long hInstance, String clazzName, long wndProc); + static native boolean DestroyWindowClass0(long hInstance, String className, long dispThreadCtx); + static native long CreateDummyDispatchThread0(); private static native boolean initIDs0(); private static native long getDummyWndProc0(); @@ -137,8 +138,6 @@ public class GDIUtil implements ToolkitProperties { private static native boolean IsChild0(long win); private static native boolean IsUndecorated0(long win); - private static native long CreateDummyWindow0(long hInstance, String className, String windowName, int x, int y, int width, int height); - - private static native long CreateDummyWindowAndMessageLoop(long hInstance, String className, String windowName, int x, int y, int width, int height); - private static native boolean SendCloseMessage(long win); + private static native long CreateDummyWindow0(long hInstance, String className, long dispThreadCtx, String windowName, int x, int y, int width, int height); + private static native boolean DestroyWindow0(long dispThreadCtx, long win); } diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java index 976693e3a..1f6cb7c05 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClass.java @@ -29,12 +29,14 @@ package jogamp.nativewindow.windows; public class RegisteredClass { - long hInstance; - String className; + private final long hInstance; + private final String className; + private final long hDDTCtx; - RegisteredClass(long hInst, String name) { - hInstance = hInst; - className = name; + RegisteredClass(long hInst, String name, long hDispatchThreadCtx) { + this.hInstance = hInst; + this.className = name; + this.hDDTCtx = hDispatchThreadCtx; } /** Application handle, same as {@link RegisteredClassFactory#getHInstance()}. */ @@ -43,6 +45,9 @@ public class RegisteredClass { /** Unique Window Class Name */ public final String getName() { return className; } + /** Unique associated dispatch thread context for this Window Class, or 0 for none. */ + public final long getHDispThreadContext() { return hDDTCtx; } + @Override - public final String toString() { return "RegisteredClass[handle 0x"+Long.toHexString(hInstance)+", "+className+"]"; } + public final String toString() { return "RegisteredClass[handle 0x"+Long.toHexString(hInstance)+", "+className+", dtx 0x"+Long.toHexString(hDDTCtx)+"]"; } } diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java index 19a48d3bf..ee41fe192 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java +++ b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java @@ -49,6 +49,7 @@ public class RegisteredClassFactory { private final String classBaseName; private final long wndProc; + private final boolean useDummyDispatchThread; private RegisteredClass sharedClass = null; private int classIter = 0; @@ -59,24 +60,29 @@ public class RegisteredClassFactory { @Override public final String toString() { return "RegisteredClassFactory[moduleHandle "+toHexString(hInstance)+", "+classBaseName+ - ", wndProc "+toHexString(wndProc)+", shared[refCount "+sharedRefCount+", class "+sharedClass+"]]"; } + ", wndProc "+toHexString(wndProc)+", useDDT "+useDummyDispatchThread+", shared[refCount "+sharedRefCount+", class "+sharedClass+"]]"; } /** * Release the {@link RegisteredClass} of all {@link RegisteredClassFactory}. */ public static void shutdownSharedClasses() { synchronized(registeredFactories) { + if( DEBUG ) { + System.err.println("RegisteredClassFactory.shutdownSharedClasses: "+registeredFactories.size()); + } for(int j=0; j<registeredFactories.size(); j++) { final RegisteredClassFactory rcf = registeredFactories.get(j); synchronized(rcf.sync) { if(null != rcf.sharedClass) { - GDIUtil.DestroyWindowClass(rcf.sharedClass.getHInstance(), rcf.sharedClass.getName()); + GDIUtil.DestroyWindowClass0(rcf.sharedClass.getHInstance(), rcf.sharedClass.getName(), rcf.sharedClass.getHDispThreadContext()); rcf.sharedClass = null; rcf.sharedRefCount = 0; rcf.classIter = 0; if(DEBUG) { - System.err.println("RegisteredClassFactory #"+j+"/"+registeredFactories.size()+" shutdownSharedClasses : "+rcf.sharedClass); + System.err.println("RegisteredClassFactory #"+j+"/"+registeredFactories.size()+": shutdownSharedClasses : "+rcf.sharedClass); } + } else if(DEBUG) { + System.err.println("RegisteredClassFactory #"+j+"/"+registeredFactories.size()+": null"); } } } @@ -86,9 +92,10 @@ public class RegisteredClassFactory { /** Application handle. */ public static long getHInstance() { return hInstance; } - public RegisteredClassFactory(String classBaseName, long wndProc) { + public RegisteredClassFactory(String classBaseName, long wndProc, boolean useDummyDispatchThread) { this.classBaseName = classBaseName; this.wndProc = wndProc; + this.useDummyDispatchThread = useDummyDispatchThread; synchronized(registeredFactories) { registeredFactories.add(this); } @@ -107,12 +114,21 @@ public class RegisteredClassFactory { // Retry with next clazz name, this could happen if more than one JVM is running clazzName = classBaseName + classIter; classIter++; - registered = GDIUtil.CreateWindowClass(hInstance, clazzName, wndProc); + registered = GDIUtil.CreateWindowClass0(hInstance, clazzName, wndProc); } if( !registered ) { throw new NativeWindowException("Error: Could not create WindowClass: "+clazzName); } - sharedClass = new RegisteredClass(hInstance, clazzName); + final long hDispatchThread; + if( useDummyDispatchThread ) { + hDispatchThread = GDIUtil.CreateDummyDispatchThread0(); + if( 0 == hDispatchThread ) { + throw new NativeWindowException("Error: Could not create DDT "+clazzName); + } + } else { + hDispatchThread = 0; + } + sharedClass = new RegisteredClass(hInstance, clazzName, hDispatchThread); if(DEBUG) { System.err.println("RegisteredClassFactory getSharedClass ("+sharedRefCount+") initialized: "+sharedClass); } @@ -137,7 +153,7 @@ public class RegisteredClassFactory { throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null"); } if( 0 == sharedRefCount ) { - GDIUtil.DestroyWindowClass(sharedClass.getHInstance(), sharedClass.getName()); + GDIUtil.DestroyWindowClass0(sharedClass.getHInstance(), sharedClass.getName(), sharedClass.getHDispThreadContext()); if(DEBUG) { System.err.println("RegisteredClassFactory releaseSharedClass ("+sharedRefCount+") released: "+sharedClass); } |