6592751: EmbeddedFrame disposal is fragile and breaks clean AppContext termination
authorson
Thu, 13 Mar 2008 16:27:20 +0300
changeset 108 deaaed5cedb7
parent 107 ed0c7cfb3666
child 109 ddfda358e547
6592751: EmbeddedFrame disposal is fragile and breaks clean AppContext termination Summary: AppContext.dispose() should be ready to get exceptions during disposal of toplevels. Also now we mark windows peers as destroyed when native object has been destroyed. Reviewed-by: art
jdk/src/share/classes/sun/awt/AppContext.java
jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java
jdk/src/windows/native/sun/windows/awt.h
jdk/src/windows/native/sun/windows/awt_Component.cpp
jdk/src/windows/native/sun/windows/awt_Object.cpp
jdk/src/windows/native/sun/windows/awt_Object.h
--- a/jdk/src/share/classes/sun/awt/AppContext.java	Thu Mar 13 16:19:32 2008 +0300
+++ b/jdk/src/share/classes/sun/awt/AppContext.java	Thu Mar 13 16:27:20 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,8 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.HashSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.beans.PropertyChangeSupport;
 import java.beans.PropertyChangeListener;
 
@@ -126,6 +128,7 @@
  * @author  Fred Ecks
  */
 public final class AppContext {
+    private static final Logger log = Logger.getLogger("sun.awt.AppContext");
 
     /* Since the contents of an AppContext are unique to each Java
      * session, this class should never be serialized. */
@@ -385,7 +388,13 @@
             public void run() {
                 Window[] windowsToDispose = Window.getOwnerlessWindows();
                 for (Window w : windowsToDispose) {
-                    w.dispose();
+                    try {
+                        w.dispose();
+                    } catch (Throwable t) {
+                        if (log.isLoggable(Level.FINER)) {
+                            log.log(Level.FINER, "exception occured while disposing app context", t);
+                        }
+                    }
                 }
                 AccessController.doPrivileged(new PrivilegedAction() {
                         public Object run() {
--- a/jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java	Thu Mar 13 16:19:32 2008 +0300
+++ b/jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java	Thu Mar 13 16:27:20 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,12 @@
         initIDs();
     }
 
-    long      pData;    // The Windows handle for the native widget.
-    Object    target;   // The associated AWT object.
+    // The Windows handle for the native widget.
+    long pData;
+    // if the native peer has been destroyed
+    boolean destroyed = false;
+    // The associated AWT object.
+    Object target;
 
     private volatile boolean disposed;
 
--- a/jdk/src/windows/native/sun/windows/awt.h	Thu Mar 13 16:19:32 2008 +0300
+++ b/jdk/src/windows/native/sun/windows/awt.h	Thu Mar 13 16:27:20 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,7 @@
     JNI_CHECK_NULL_GOTO(peer, "peer", where);                             \
     pData = JNI_GET_PDATA(peer);                                          \
     if (pData == NULL) {                                                  \
-        JNU_ThrowNullPointerException(env, "null pData");                 \
+        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
         goto where;                                                       \
     }                                                                     \
 }
@@ -63,7 +63,7 @@
     JNI_CHECK_NULL_RETURN(peer, "peer");                                  \
     pData = JNI_GET_PDATA(peer);                                          \
     if (pData == NULL) {                                                  \
-        JNU_ThrowNullPointerException(env, "null pData");                 \
+        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
         return;                                                           \
     }                                                                     \
 }
@@ -96,7 +96,7 @@
     JNI_CHECK_NULL_RETURN_NULL(peer, "peer");                             \
     pData = JNI_GET_PDATA(peer);                                          \
     if (pData == NULL) {                                                  \
-        JNU_ThrowNullPointerException(env, "null pData");                 \
+        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
         return 0;                                                         \
     }                                                                     \
 }
@@ -105,16 +105,27 @@
     JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val);                         \
     pData = JNI_GET_PDATA(peer);                                          \
     if (pData == NULL) {                                                  \
-        JNU_ThrowNullPointerException(env, "null pData");                 \
+        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
         return val;                                                       \
     }                                                                     \
 }
 
+#define THROW_NULL_PDATA_IF_NOT_DESTROYED(peer) {                         \
+    jboolean destroyed = JNI_GET_DESTROYED(peer);                         \
+    if (destroyed != JNI_TRUE) {                                          \
+        JNU_ThrowNullPointerException(env, "null pData");                 \
+    }                                                                     \
+}
+
 #define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID)
+#define JNI_GET_DESTROYED(peer) env->GetBooleanField(peer, AwtObject::destroyedID)
 
 #define JNI_SET_PDATA(peer, data) env->SetLongField(peer,                  \
-                                                   AwtObject::pDataID,    \
-                                                   (jlong)data)
+                                                    AwtObject::pDataID,    \
+                                                    (jlong)data)
+#define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer,                   \
+                                                     AwtObject::destroyedID, \
+                                                     JNI_TRUE)
 /*  /NEW JNI */
 
 /*
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp	Thu Mar 13 16:19:32 2008 +0300
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp	Thu Mar 13 16:27:20 2008 +0300
@@ -5403,6 +5403,7 @@
     if (m_peerObject) {
         env->SetLongField(m_peerObject, AwtComponent::hwndID, 0);
         JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));
+        JNI_SET_DESTROYED(m_peerObject);
         env->DeleteGlobalRef(m_peerObject);
         m_peerObject = NULL;
     }
--- a/jdk/src/windows/native/sun/windows/awt_Object.cpp	Thu Mar 13 16:19:32 2008 +0300
+++ b/jdk/src/windows/native/sun/windows/awt_Object.cpp	Thu Mar 13 16:27:20 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
  */
 
 jfieldID AwtObject::pDataID;
+jfieldID AwtObject::destroyedID;
 jfieldID AwtObject::targetID;
 jclass AwtObject::wObjectPeerClass;
 jmethodID AwtObject::getPeerForTargetMID;
@@ -223,6 +224,7 @@
 
     AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls);
     AwtObject::pDataID = env->GetFieldID(cls, "pData", "J");
+    AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z");
     AwtObject::targetID = env->GetFieldID(cls, "target",
                                               "Ljava/lang/Object;");
 
@@ -233,6 +235,7 @@
     AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;");
 
     DASSERT(AwtObject::pDataID != NULL);
+    DASSERT(AwtObject::destroyedID != NULL);
     DASSERT(AwtObject::targetID != NULL);
     DASSERT(AwtObject::getPeerForTargetMID != NULL);
     DASSERT(AwtObject::createErrorID != NULL);
--- a/jdk/src/windows/native/sun/windows/awt_Object.h	Thu Mar 13 16:19:32 2008 +0300
+++ b/jdk/src/windows/native/sun/windows/awt_Object.h	Thu Mar 13 16:27:20 2008 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,6 +51,7 @@
 
     /* sun.awt.windows.WObjectPeer field and method ids */
     static jfieldID pDataID;
+    static jfieldID destroyedID;
     static jfieldID targetID;
 
     static jmethodID getPeerForTargetMID;