提交 5fadc98d 编写于 作者: B bagiras

7073337: Crash after playing Java game on Pogo

Reviewed-by: art, uta
上级 a258c6e6
...@@ -615,6 +615,14 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -615,6 +615,14 @@ public abstract class WComponentPeer extends WObjectPeer
_dispose(); _dispose();
} }
public void disposeLater() {
postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), new Runnable() {
public void run() {
dispose();
}
}));
}
public synchronized void setForeground(Color c) { public synchronized void setForeground(Color c) {
foreground = c; foreground = c;
_setForeground(c.getRGB()); _setForeground(c.getRGB());
......
...@@ -183,6 +183,7 @@ jmethodID AwtComponent::isEnabledMID; ...@@ -183,6 +183,7 @@ jmethodID AwtComponent::isEnabledMID;
jmethodID AwtComponent::getLocationOnScreenMID; jmethodID AwtComponent::getLocationOnScreenMID;
jmethodID AwtComponent::replaceSurfaceDataMID; jmethodID AwtComponent::replaceSurfaceDataMID;
jmethodID AwtComponent::replaceSurfaceDataLaterMID; jmethodID AwtComponent::replaceSurfaceDataLaterMID;
jmethodID AwtComponent::disposeLaterMID;
HKL AwtComponent::m_hkl = ::GetKeyboardLayout(0); HKL AwtComponent::m_hkl = ::GetKeyboardLayout(0);
LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0)); LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0));
...@@ -246,6 +247,7 @@ AwtComponent::AwtComponent() ...@@ -246,6 +247,7 @@ AwtComponent::AwtComponent()
m_hCursorCache = NULL; m_hCursorCache = NULL;
m_bSubclassed = FALSE; m_bSubclassed = FALSE;
m_bPauseDestroy = FALSE;
m_MessagesProcessing = 0; m_MessagesProcessing = 0;
m_wheelRotationAmount = 0; m_wheelRotationAmount = 0;
...@@ -319,6 +321,12 @@ void AwtComponent::Dispose() ...@@ -319,6 +321,12 @@ void AwtComponent::Dispose()
m_brushBackground = NULL; m_brushBackground = NULL;
} }
if (m_bPauseDestroy) {
// AwtComponent::WmNcDestroy could be released now
m_bPauseDestroy = FALSE;
m_hwnd = NULL;
}
// The component instance is deleted using AwtObject::Dispose() method // The component instance is deleted using AwtObject::Dispose() method
AwtObject::Dispose(); AwtObject::Dispose();
} }
...@@ -1377,6 +1385,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) ...@@ -1377,6 +1385,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
case WM_CREATE: mr = WmCreate(); break; case WM_CREATE: mr = WmCreate(); break;
case WM_CLOSE: mr = WmClose(); break; case WM_CLOSE: mr = WmClose(); break;
case WM_DESTROY: mr = WmDestroy(); break; case WM_DESTROY: mr = WmDestroy(); break;
case WM_NCDESTROY: mr = WmNcDestroy(); break;
case WM_ERASEBKGND: case WM_ERASEBKGND:
mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break; mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break;
...@@ -1965,10 +1974,24 @@ LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -1965,10 +1974,24 @@ LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
*/ */
MsgRouting AwtComponent::WmDestroy() MsgRouting AwtComponent::WmDestroy()
{ {
// fix for 6259348: we should enter the SyncCall critical section before return mrConsume;
// disposing the native object, that is value 1 of lParam is intended for }
if(m_peerObject != NULL) { // is not being terminating
AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)m_peerObject, (LPARAM)1); /*
* This message should only be received when a window is destroyed by
* Windows, and not Java. It is sent only after child windows were destroyed.
*/
MsgRouting AwtComponent::WmNcDestroy()
{
if (m_peerObject != NULL) { // is not being terminating
// Stay in this handler until AwtComponent::Dispose is called.
m_bPauseDestroy = TRUE;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
// Post invocation event for WObjectPeer.dispose to EDT
env->CallVoidMethod(m_peerObject, AwtComponent::disposeLaterMID);
// Wait until AwtComponent::Dispose is called
AwtToolkit::GetInstance().PumpToDestroy(this);
} }
return mrConsume; return mrConsume;
...@@ -6300,6 +6323,7 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls) ...@@ -6300,6 +6323,7 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
env->GetMethodID(peerCls, "replaceSurfaceData", "()V"); env->GetMethodID(peerCls, "replaceSurfaceData", "()V");
AwtComponent::replaceSurfaceDataLaterMID = AwtComponent::replaceSurfaceDataLaterMID =
env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V"); env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V");
AwtComponent::disposeLaterMID = env->GetMethodID(peerCls, "disposeLater", "()V");
DASSERT(AwtComponent::xID); DASSERT(AwtComponent::xID);
DASSERT(AwtComponent::yID); DASSERT(AwtComponent::yID);
...@@ -6318,6 +6342,8 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls) ...@@ -6318,6 +6342,8 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
DASSERT(AwtComponent::getLocationOnScreenMID); DASSERT(AwtComponent::getLocationOnScreenMID);
DASSERT(AwtComponent::replaceSurfaceDataMID); DASSERT(AwtComponent::replaceSurfaceDataMID);
DASSERT(AwtComponent::replaceSurfaceDataLaterMID); DASSERT(AwtComponent::replaceSurfaceDataLaterMID);
DASSERT(AwtComponent::disposeLaterMID);
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
......
...@@ -119,6 +119,7 @@ public: ...@@ -119,6 +119,7 @@ public:
static jmethodID getLocationOnScreenMID; static jmethodID getLocationOnScreenMID;
static jmethodID replaceSurfaceDataMID; static jmethodID replaceSurfaceDataMID;
static jmethodID replaceSurfaceDataLaterMID; static jmethodID replaceSurfaceDataLaterMID;
static jmethodID disposeLaterMID;
static const UINT WmAwtIsComponent; static const UINT WmAwtIsComponent;
static jint * masks; //InputEvent mask array static jint * masks; //InputEvent mask array
...@@ -490,6 +491,7 @@ public: ...@@ -490,6 +491,7 @@ public:
virtual MsgRouting WmCreate() {return mrDoDefault;} virtual MsgRouting WmCreate() {return mrDoDefault;}
virtual MsgRouting WmClose() {return mrDoDefault;} virtual MsgRouting WmClose() {return mrDoDefault;}
virtual MsgRouting WmDestroy(); virtual MsgRouting WmDestroy();
virtual MsgRouting WmNcDestroy();
virtual MsgRouting WmActivate(UINT nState, BOOL fMinimized, HWND opposite) virtual MsgRouting WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
{ {
...@@ -711,6 +713,10 @@ public: ...@@ -711,6 +713,10 @@ public:
return m_MessagesProcessing == 0; return m_MessagesProcessing == 0;
} }
BOOL IsDestroyPaused() const {
return m_bPauseDestroy;
}
protected: protected:
static AwtComponent* GetComponentImpl(HWND hWnd); static AwtComponent* GetComponentImpl(HWND hWnd);
...@@ -752,6 +758,7 @@ private: ...@@ -752,6 +758,7 @@ private:
UINT m_mouseButtonClickAllowed; UINT m_mouseButtonClickAllowed;
BOOL m_bSubclassed; BOOL m_bSubclassed;
BOOL m_bPauseDestroy;
COLORREF m_colorForeground; COLORREF m_colorForeground;
COLORREF m_colorBackground; COLORREF m_colorBackground;
......
...@@ -733,26 +733,13 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message, ...@@ -733,26 +733,13 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
return 0; return 0;
} }
case WM_AWT_DISPOSE: { case WM_AWT_DISPOSE: {
BOOL canDispose = TRUE; if(wParam != NULL) {
CriticalSection &syncCS = AwtToolkit::GetInstance().GetSyncCS(); jobject self = (jobject)wParam;
int shouldEnterCriticalSection = (int)lParam; AwtObject *o = (AwtObject *) JNI_GET_PDATA(self);
if (shouldEnterCriticalSection == 1) { env->DeleteGlobalRef(self);
canDispose = syncCS.TryEnter(); if(o != NULL && theAwtObjectList.Remove(o)) {
} o->Dispose();
if (canDispose) {
if(wParam != NULL) {
jobject self = (jobject)wParam;
AwtObject *o = (AwtObject *) JNI_GET_PDATA(self);
env->DeleteGlobalRef(self);
if(o != NULL && theAwtObjectList.Remove(o)) {
o->Dispose();
}
if (shouldEnterCriticalSection) {
syncCS.Leave();
}
} }
} else {
AwtToolkit::GetInstance().PostMessage(WM_AWT_DISPOSE, wParam, lParam);
} }
return 0; return 0;
} }
...@@ -1340,27 +1327,48 @@ BOOL AwtToolkit::PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc) ...@@ -1340,27 +1327,48 @@ BOOL AwtToolkit::PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc)
while (!m_breakMessageLoop && (*lpPeekMessageFunc)(msg)) { while (!m_breakMessageLoop && (*lpPeekMessageFunc)(msg)) {
foundOne = TRUE; foundOne = TRUE;
if (msg.message == WM_QUIT) { ProcessMsg(msg);
m_breakMessageLoop = TRUE;
m_messageLoopResult = static_cast<UINT>(msg.wParam);
if (m_messageLoopResult == EXIT_ALL_ENCLOSING_LOOPS)
::PostQuitMessage(static_cast<int>(msg.wParam)); // make sure all loops exit
break;
}
else if (msg.message != WM_NULL) {
/*
* The AWT in standalone mode (that is, dynamically loaded from the
* Java VM) doesn't have any translation tables to worry about, so
* TranslateAccelerator isn't called.
*/
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
} }
return foundOne; return foundOne;
} }
void AwtToolkit::PumpToDestroy(class AwtComponent* p)
{
MSG msg;
DASSERT(AwtToolkit::PrimaryIdleFunc != NULL);
DASSERT(AwtToolkit::CommonPeekMessageFunc != NULL);
while (p->IsDestroyPaused() && !m_breakMessageLoop) {
PrimaryIdleFunc();
while (p->IsDestroyPaused() && !m_breakMessageLoop && CommonPeekMessageFunc(msg)) {
ProcessMsg(msg);
}
}
}
void AwtToolkit::ProcessMsg(MSG& msg)
{
if (msg.message == WM_QUIT) {
m_breakMessageLoop = TRUE;
m_messageLoopResult = static_cast<UINT>(msg.wParam);
if (m_messageLoopResult == EXIT_ALL_ENCLOSING_LOOPS)
::PostQuitMessage(static_cast<int>(msg.wParam)); // make sure all loops exit
}
else if (msg.message != WM_NULL) {
/*
* The AWT in standalone mode (that is, dynamically loaded from the
* Java VM) doesn't have any translation tables to worry about, so
* TranslateAccelerator isn't called.
*/
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
VOID CALLBACK VOID CALLBACK
AwtToolkit::PrimaryIdleFunc() { AwtToolkit::PrimaryIdleFunc() {
AwtToolkit::SetBusy(FALSE); AwtToolkit::SetBusy(FALSE);
......
...@@ -305,6 +305,8 @@ public: ...@@ -305,6 +305,8 @@ public:
UINT MessageLoop(IDLEPROC lpIdleFunc, PEEKMESSAGEPROC lpPeekMessageFunc); UINT MessageLoop(IDLEPROC lpIdleFunc, PEEKMESSAGEPROC lpPeekMessageFunc);
BOOL PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc); BOOL PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc);
void PumpToDestroy(class AwtComponent* p);
void ProcessMsg(MSG& msg);
BOOL PreProcessMsg(MSG& msg); BOOL PreProcessMsg(MSG& msg);
BOOL PreProcessMouseMsg(class AwtComponent* p, MSG& msg); BOOL PreProcessMouseMsg(class AwtComponent* p, MSG& msg);
BOOL PreProcessKeyMsg(class AwtComponent* p, MSG& msg); BOOL PreProcessKeyMsg(class AwtComponent* p, MSG& msg);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册