提交 5f7f97a4 编写于 作者: S son

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
上级 ece4d22e
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -40,6 +40,8 @@ import java.util.IdentityHashMap; ...@@ -40,6 +40,8 @@ import java.util.IdentityHashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.HashSet; import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
...@@ -126,6 +128,7 @@ import java.beans.PropertyChangeListener; ...@@ -126,6 +128,7 @@ import java.beans.PropertyChangeListener;
* @author Fred Ecks * @author Fred Ecks
*/ */
public final class AppContext { 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 /* Since the contents of an AppContext are unique to each Java
* session, this class should never be serialized. */ * session, this class should never be serialized. */
...@@ -385,7 +388,13 @@ public final class AppContext { ...@@ -385,7 +388,13 @@ public final class AppContext {
public void run() { public void run() {
Window[] windowsToDispose = Window.getOwnerlessWindows(); Window[] windowsToDispose = Window.getOwnerlessWindows();
for (Window w : windowsToDispose) { 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() { AccessController.doPrivileged(new PrivilegedAction() {
public Object run() { public Object run() {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,8 +30,12 @@ abstract class WObjectPeer { ...@@ -30,8 +30,12 @@ abstract class WObjectPeer {
initIDs(); initIDs();
} }
long pData; // The Windows handle for the native widget. // The Windows handle for the native widget.
Object target; // The associated AWT object. long pData;
// if the native peer has been destroyed
boolean destroyed = false;
// The associated AWT object.
Object target;
private volatile boolean disposed; private volatile boolean disposed;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -47,7 +47,7 @@ typedef AwtObject* PDATA; ...@@ -47,7 +47,7 @@ typedef AwtObject* PDATA;
JNI_CHECK_NULL_GOTO(peer, "peer", where); \ JNI_CHECK_NULL_GOTO(peer, "peer", where); \
pData = JNI_GET_PDATA(peer); \ pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \ if (pData == NULL) { \
JNU_ThrowNullPointerException(env, "null pData"); \ THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
goto where; \ goto where; \
} \ } \
} }
...@@ -63,7 +63,7 @@ typedef AwtObject* PDATA; ...@@ -63,7 +63,7 @@ typedef AwtObject* PDATA;
JNI_CHECK_NULL_RETURN(peer, "peer"); \ JNI_CHECK_NULL_RETURN(peer, "peer"); \
pData = JNI_GET_PDATA(peer); \ pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \ if (pData == NULL) { \
JNU_ThrowNullPointerException(env, "null pData"); \ THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
return; \ return; \
} \ } \
} }
...@@ -96,7 +96,7 @@ typedef AwtObject* PDATA; ...@@ -96,7 +96,7 @@ typedef AwtObject* PDATA;
JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \ JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \
pData = JNI_GET_PDATA(peer); \ pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \ if (pData == NULL) { \
JNU_ThrowNullPointerException(env, "null pData"); \ THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
return 0; \ return 0; \
} \ } \
} }
...@@ -105,16 +105,27 @@ typedef AwtObject* PDATA; ...@@ -105,16 +105,27 @@ typedef AwtObject* PDATA;
JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \ JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \
pData = JNI_GET_PDATA(peer); \ pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \ if (pData == NULL) { \
JNU_ThrowNullPointerException(env, "null pData"); \ THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
return val; \ 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_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, \ #define JNI_SET_PDATA(peer, data) env->SetLongField(peer, \
AwtObject::pDataID, \ AwtObject::pDataID, \
(jlong)data) (jlong)data)
#define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer, \
AwtObject::destroyedID, \
JNI_TRUE)
/* /NEW JNI */ /* /NEW JNI */
/* /*
......
...@@ -5403,6 +5403,7 @@ void AwtComponent::UnlinkObjects() ...@@ -5403,6 +5403,7 @@ void AwtComponent::UnlinkObjects()
if (m_peerObject) { if (m_peerObject) {
env->SetLongField(m_peerObject, AwtComponent::hwndID, 0); env->SetLongField(m_peerObject, AwtComponent::hwndID, 0);
JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL)); JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));
JNI_SET_DESTROYED(m_peerObject);
env->DeleteGlobalRef(m_peerObject); env->DeleteGlobalRef(m_peerObject);
m_peerObject = NULL; m_peerObject = NULL;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -39,6 +39,7 @@ static BOOL reportEvents = FALSE; ...@@ -39,6 +39,7 @@ static BOOL reportEvents = FALSE;
*/ */
jfieldID AwtObject::pDataID; jfieldID AwtObject::pDataID;
jfieldID AwtObject::destroyedID;
jfieldID AwtObject::targetID; jfieldID AwtObject::targetID;
jclass AwtObject::wObjectPeerClass; jclass AwtObject::wObjectPeerClass;
jmethodID AwtObject::getPeerForTargetMID; jmethodID AwtObject::getPeerForTargetMID;
...@@ -223,6 +224,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) { ...@@ -223,6 +224,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) {
AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls); AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls);
AwtObject::pDataID = env->GetFieldID(cls, "pData", "J"); AwtObject::pDataID = env->GetFieldID(cls, "pData", "J");
AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z");
AwtObject::targetID = env->GetFieldID(cls, "target", AwtObject::targetID = env->GetFieldID(cls, "target",
"Ljava/lang/Object;"); "Ljava/lang/Object;");
...@@ -233,6 +235,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) { ...@@ -233,6 +235,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) {
AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;"); AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;");
DASSERT(AwtObject::pDataID != NULL); DASSERT(AwtObject::pDataID != NULL);
DASSERT(AwtObject::destroyedID != NULL);
DASSERT(AwtObject::targetID != NULL); DASSERT(AwtObject::targetID != NULL);
DASSERT(AwtObject::getPeerForTargetMID != NULL); DASSERT(AwtObject::getPeerForTargetMID != NULL);
DASSERT(AwtObject::createErrorID != NULL); DASSERT(AwtObject::createErrorID != NULL);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -51,6 +51,7 @@ public: ...@@ -51,6 +51,7 @@ public:
/* sun.awt.windows.WObjectPeer field and method ids */ /* sun.awt.windows.WObjectPeer field and method ids */
static jfieldID pDataID; static jfieldID pDataID;
static jfieldID destroyedID;
static jfieldID targetID; static jfieldID targetID;
static jmethodID getPeerForTargetMID; static jmethodID getPeerForTargetMID;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册