Skip to content

Commit

Permalink
Workaround Bug 910 (IcedTea-Web): NewtCanvasAWT shall postpone JAWTWi…
Browse files Browse the repository at this point in the history
…ndow destruction via explicit set flag.

IcedTea-Web_1.5pre+rbc73a1362e9c still issues NewtCanvasAWT.removeNotify()
before before Applet.destroy(), i.e. removes NewtCanvasAWT from the Container
ahead of time (Applet protocol destroy()).

However, it fixes the non AWT-EDT issue, i.e. calls NewtCanvasAWT.removeNotify()
from the actual AWT-EDT - good.

Since the root cause still exist, we cannot use heuristics as described in
Bug 910 comment 9, but need to set a flag in NewtCanvasAWT to skip JAWT destruction
and remove it latter within Applet.destroy().

NewtCanvasAWT.removeNotify.0 - isApplet true @ [AWT-EventQueue-0, isAWT-EDT true]
  • Loading branch information
sgothel committed Nov 25, 2013
1 parent d5c25aa commit 1617b3e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 20 deletions.
43 changes: 23 additions & 20 deletions src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,10 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
private final AWTAdapter awtMouseAdapter;
private final AWTAdapter awtKeyAdapter;

/** Mitigates Bug 910 (IcedTea-Web), i.e. crash via removeNotify() from 'other' AWT-EDT. */
private boolean addedOnAWTEDT = false;
/** Mitigates Bug 910 (IcedTea-Web), i.e. crash via removeNotify() from 'other' AWT-EDT. */
/** Mitigates Bug 910 (IcedTea-Web), i.e. crash via removeNotify() invoked before Applet.destroy(). */
private boolean destroyJAWTPending = false;
/** Mitigates Bug 910 (IcedTea-Web), i.e. crash via removeNotify() invoked before Applet.destroy(). */
private boolean skipJAWTDestroy = false;

/** Safeguard for AWTWindowClosingProtocol and 'removeNotify()' on other thread than AWT-EDT. */
private volatile boolean componentAdded = false;
Expand Down Expand Up @@ -425,6 +425,20 @@ public WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) {
return awtWindowClosingProtocol.setDefaultCloseOperation(op);
}

/**
* Mitigates Bug 910 (IcedTea-Web), i.e. crash via removeNotify() invoked before Applet.destroy().
* <p>
* <code>skipJAWTDestroy</code> defaults to <code>false</code>.
* Due to above IcedTea-Web issue the <code>Applet</code> code needs to avoid JAWT destruction before
* <code>Applet.destroy()</code> is reached by setting <code>skipJAWTDestroy</code> to <code>true</code>.
* Afterwards the value should be reset to <code>false</code> and {@link #destroy()} needs to be called,
* which finally will perform the pending JAWT destruction.
* </p>
*/
public final void setSkipJAWTDestroy(boolean v) { skipJAWTDestroy = v; }
/** See {@link #setSkipJAWTDestroy(boolean)}. */
public final boolean getSkipJAWTDestroy() { return skipJAWTDestroy; }

private final void determineIfApplet() {
isApplet = false;
Component c = this;
Expand All @@ -450,9 +464,8 @@ public void addNotify() {

synchronized(sync) {
determineIfApplet();
addedOnAWTEDT = EventQueue.isDispatchThread();
if(DEBUG) {
System.err.println("NewtCanvasAWT.addNotify.0 - isApplet "+isApplet+", addedOnAWTEDT "+addedOnAWTEDT+" @ "+currentThreadName());
System.err.println("NewtCanvasAWT.addNotify.0 - isApplet "+isApplet+", addedOnAWTEDT "+EventQueue.isDispatchThread()+" @ "+currentThreadName());
Thread.dumpStack();
}
jawtWindow = NewtFactoryAWT.getNativeWindow(NewtCanvasAWT.this, null != newtChild ? newtChild.getRequestedCapabilities() : null);
Expand Down Expand Up @@ -514,18 +527,9 @@ public void run() {
private final void destroyImpl(boolean removeNotify, boolean windowClosing) {
synchronized(sync) {
final java.awt.Container cont = AWTMisc.getContainer(this);
/**
* Mitigates Bug 910 (IcedTea-Web), i.e. crash via removeNotify() from 'other' AWT-EDT.
*
* 'destroyJAWT' defaults to 'true' - however, IcedTea-Web (Applet) issues removeNotify() from
* a different AWT-EDT thread, which is not recognized as an AWT-EDT thread!
* This 'different AWT-EDT thread' maybe caused due to a AppContext issue in IcedTea-Web.
*/
final boolean isOnAWTEDT = EventQueue.isDispatchThread();
final boolean destroyJAWTOK = !isApplet || !addedOnAWTEDT || isOnAWTEDT;
if(DEBUG) {
System.err.println("NewtCanvasAWT.destroyImpl @ "+currentThreadName());
System.err.println("NewtCanvasAWT.destroyImpl.0 - isApplet "+isApplet+", addedOnAWTEDT "+addedOnAWTEDT+", isOnAWTEDT "+isOnAWTEDT+" -> destroyJAWTOK "+destroyJAWTOK+
System.err.println("NewtCanvasAWT.destroyImpl.0 - isApplet "+isApplet+", isOnAWTEDT "+EventQueue.isDispatchThread()+", skipJAWTDestroy "+skipJAWTDestroy+
"; removeNotify "+removeNotify+", windowClosing "+windowClosing+", destroyJAWTPending "+destroyJAWTPending+
", hasJAWT "+(null!=jawtWindow)+", hasNEWT "+(null!=newtChild)+
"): nw "+newtWinHandleToHexString(newtChild)+", from "+cont);
Expand All @@ -545,14 +549,13 @@ private final void destroyImpl(boolean removeNotify, boolean windowClosing) {
}
}
if( ( destroyJAWTPending || removeNotify || windowClosing ) && null!=jawtWindow ) {
if( destroyJAWTOK ) {
if( skipJAWTDestroy ) {
// Bug 910 - See setSkipJAWTDestroy(boolean)
destroyJAWTPending = true;
} else {
NewtFactoryAWT.destroyNativeWindow(jawtWindow);
jawtWindow=null;
destroyJAWTPending = false;
} else {
// Bug 910 - See above FIXME
destroyJAWTPending = true;
System.err.println("Info: JAWT destruction pending due to: isApplet "+isApplet+", addedOnAWTEDT "+addedOnAWTEDT+", isOnAWTEDT "+isOnAWTEDT+" -> destroyJAWTOK "+destroyJAWTOK);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ public void run() {
AWTEDTExecutor.singleton.invoke(true, new Runnable() {
public void run() {
newtCanvasAWT = new NewtCanvasAWT(glWindow);
newtCanvasAWT.setSkipJAWTDestroy(true); // Bug 910
container.add(newtCanvasAWT, BorderLayout.CENTER);
container.validate();
} } );
Expand Down Expand Up @@ -307,6 +308,7 @@ public void destroy() {
public void run() {
glWindow.setVisible(false); // hide 1st
if( null != newtCanvasAWT ) {
newtCanvasAWT.setSkipJAWTDestroy(false); // Bug 910
remove(newtCanvasAWT); // remove newtCanvasAWT incl. glWindow.reparentWindow(null) if not done yet!
newtCanvasAWT.destroy();
}
Expand Down

0 comments on commit 1617b3e

Please sign in to comment.