8232114: JVM crashed at imjpapi.dll in native code
Reviewed-by: serb, alitvinov
This commit is contained in:
parent
4d4161a57e
commit
0643f3aa4c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. 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
|
||||
@ -57,7 +57,7 @@ Java_sun_awt_windows_WInputMethod_createNativeContext(JNIEnv *env, jobject self)
|
||||
TRY;
|
||||
|
||||
// use special message to call ImmCreateContext() in main thread.
|
||||
return (jint)AwtToolkit::GetInstance().SendMessage(WM_AWT_CREATECONTEXT);
|
||||
return (jint)AwtToolkit::GetInstance().InvokeInputMethodFunction(WM_AWT_CREATECONTEXT);
|
||||
|
||||
CATCH_BAD_ALLOC_RET(0);
|
||||
}
|
||||
@ -74,7 +74,7 @@ Java_sun_awt_windows_WInputMethod_destroyNativeContext(JNIEnv *env, jobject self
|
||||
TRY_NO_VERIFY;
|
||||
|
||||
// use special message to call ImmDestroyContext() in main thread.
|
||||
AwtToolkit::GetInstance().SendMessage(WM_AWT_DESTROYCONTEXT, context, 0);
|
||||
AwtToolkit::GetInstance().InvokeInputMethodFunction(WM_AWT_DESTROYCONTEXT, context, 0);
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
@ -101,7 +101,7 @@ Java_sun_awt_windows_WInputMethod_enableNativeIME(JNIEnv *env, jobject self, job
|
||||
enis->context = context;
|
||||
enis->useNativeCompWindow = useNativeCompWindow;
|
||||
|
||||
AwtToolkit::GetInstance().SendMessage(WM_AWT_ASSOCIATECONTEXT,
|
||||
AwtToolkit::GetInstance().InvokeInputMethodFunction(WM_AWT_ASSOCIATECONTEXT,
|
||||
reinterpret_cast<WPARAM>(enis), (LPARAM)0);
|
||||
// global refs are deleted in message handler
|
||||
|
||||
@ -128,7 +128,7 @@ Java_sun_awt_windows_WInputMethod_disableNativeIME(JNIEnv *env, jobject self, jo
|
||||
enis->context = NULL;
|
||||
enis->useNativeCompWindow = JNI_TRUE;
|
||||
|
||||
AwtToolkit::GetInstance().SendMessage(WM_AWT_ASSOCIATECONTEXT,
|
||||
AwtToolkit::GetInstance().InvokeInputMethodFunction(WM_AWT_ASSOCIATECONTEXT,
|
||||
reinterpret_cast<WPARAM>(enis), (LPARAM)0);
|
||||
// global refs are deleted in message handler
|
||||
|
||||
@ -205,7 +205,7 @@ Java_sun_awt_windows_WInputMethod_endCompositionNative(JNIEnv *env, jobject self
|
||||
// 10/29/98 - Changed to commit it according to the flag.
|
||||
|
||||
// use special message to call ImmNotifyIME() in main thread.
|
||||
AwtToolkit::GetInstance().SendMessage(WM_AWT_ENDCOMPOSITION, context,
|
||||
AwtToolkit::GetInstance().InvokeInputMethodFunction(WM_AWT_ENDCOMPOSITION, context,
|
||||
(LPARAM)(flag != sun_awt_windows_WInputMethod_DISCARD_INPUT));
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
@ -222,7 +222,7 @@ Java_sun_awt_windows_WInputMethod_setConversionStatus(JNIEnv *env, jobject self,
|
||||
TRY;
|
||||
|
||||
// use special message to call ImmSetConversionStatus() in main thread.
|
||||
AwtToolkit::GetInstance().SendMessage(WM_AWT_SETCONVERSIONSTATUS,
|
||||
AwtToolkit::GetInstance().InvokeInputMethodFunction(WM_AWT_SETCONVERSIONSTATUS,
|
||||
context,
|
||||
MAKELPARAM((WORD)request, (WORD)0));
|
||||
|
||||
@ -240,7 +240,7 @@ Java_sun_awt_windows_WInputMethod_getConversionStatus(JNIEnv *env, jobject self,
|
||||
TRY;
|
||||
|
||||
// use special message to call ImmSetConversionStatus() in main thread.
|
||||
return (jint) AwtToolkit::GetInstance().SendMessage(
|
||||
return (jint) AwtToolkit::GetInstance().InvokeInputMethodFunction(
|
||||
WM_AWT_GETCONVERSIONSTATUS, context, 0);
|
||||
|
||||
CATCH_BAD_ALLOC_RET(0);
|
||||
@ -257,7 +257,7 @@ Java_sun_awt_windows_WInputMethod_setOpenStatus(JNIEnv *env, jobject self, jint
|
||||
TRY;
|
||||
|
||||
// use special message to call ImmSetConversionStatus() in main thread.
|
||||
AwtToolkit::GetInstance().SendMessage(WM_AWT_SETOPENSTATUS,
|
||||
AwtToolkit::GetInstance().InvokeInputMethodFunction(WM_AWT_SETOPENSTATUS,
|
||||
context, flag);
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
@ -274,7 +274,7 @@ Java_sun_awt_windows_WInputMethod_getOpenStatus(JNIEnv *env, jobject self, jint
|
||||
TRY;
|
||||
|
||||
// use special message to call ImmSetConversionStatus() in main thread.
|
||||
return (jboolean)(AwtToolkit::GetInstance().SendMessage(
|
||||
return (jboolean)(AwtToolkit::GetInstance().InvokeInputMethodFunction(
|
||||
WM_AWT_GETOPENSTATUS,
|
||||
context, 0));
|
||||
CATCH_BAD_ALLOC_RET(0);
|
||||
@ -392,7 +392,7 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WInputMethod_setStatusWindowVisible
|
||||
jobject peerGlobalRef = env->NewGlobalRef(peer);
|
||||
|
||||
// use special message to access pData on the toolkit thread
|
||||
LRESULT res = AwtToolkit::GetInstance().SendMessage(WM_AWT_GET_DEFAULT_IME_HANDLER,
|
||||
LRESULT res = AwtToolkit::GetInstance().InvokeInputMethodFunction(WM_AWT_GET_DEFAULT_IME_HANDLER,
|
||||
reinterpret_cast<WPARAM>(peerGlobalRef), 0);
|
||||
// global ref is deleted in message handler
|
||||
|
||||
@ -431,7 +431,7 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WInputMethod_openCandidateWindow
|
||||
// See CR 4805862, AwtToolkit::WndProc
|
||||
|
||||
// use special message to open candidate window in main thread.
|
||||
AwtToolkit::GetInstance().SendMessage(WM_AWT_OPENCANDIDATEWINDOW,
|
||||
AwtToolkit::GetInstance().InvokeInputMethodFunction(WM_AWT_OPENCANDIDATEWINDOW,
|
||||
(WPARAM)peerGlobalRef, MAKELONG(x, y));
|
||||
// global ref is deleted in message handler
|
||||
|
||||
|
@ -343,6 +343,7 @@ AwtToolkit::AwtToolkit() {
|
||||
::GetKeyboardState(m_lastKeyboardState);
|
||||
|
||||
m_waitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
m_inputMethodWaitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
isInDoDragDropLoop = FALSE;
|
||||
eventNumber = 0;
|
||||
}
|
||||
@ -777,6 +778,7 @@ BOOL AwtToolkit::Dispose() {
|
||||
delete tk.m_cmdIDs;
|
||||
|
||||
::CloseHandle(m_waitEvent);
|
||||
::CloseHandle(m_inputMethodWaitEvent);
|
||||
|
||||
tk.m_isDisposed = TRUE;
|
||||
|
||||
@ -1087,11 +1089,17 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
// it returs with no error. (This restriction is not documented)
|
||||
// So we must use thse messages to call these APIs in main thread.
|
||||
case WM_AWT_CREATECONTEXT: {
|
||||
return reinterpret_cast<LRESULT>(
|
||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||
tk.m_inputMethodData = reinterpret_cast<LRESULT>(
|
||||
reinterpret_cast<void*>(ImmCreateContext()));
|
||||
::SetEvent(tk.m_inputMethodWaitEvent);
|
||||
return tk.m_inputMethodData;
|
||||
}
|
||||
case WM_AWT_DESTROYCONTEXT: {
|
||||
ImmDestroyContext((HIMC)wParam);
|
||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||
tk.m_inputMethodData = 0;
|
||||
::SetEvent(tk.m_inputMethodWaitEvent);
|
||||
return 0;
|
||||
}
|
||||
case WM_AWT_ASSOCIATECONTEXT: {
|
||||
@ -1117,17 +1125,21 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
}
|
||||
|
||||
delete data;
|
||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||
tk.m_inputMethodData = 0;
|
||||
::SetEvent(tk.m_inputMethodWaitEvent);
|
||||
return 0;
|
||||
}
|
||||
case WM_AWT_GET_DEFAULT_IME_HANDLER: {
|
||||
LRESULT ret = (LRESULT)FALSE;
|
||||
jobject peer = (jobject)wParam;
|
||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||
|
||||
AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
|
||||
if (comp != NULL) {
|
||||
HWND defaultIMEHandler = ImmGetDefaultIMEWnd(comp->GetHWnd());
|
||||
if (defaultIMEHandler != NULL) {
|
||||
AwtToolkit::GetInstance().SetInputMethodWindow(defaultIMEHandler);
|
||||
tk.SetInputMethodWindow(defaultIMEHandler);
|
||||
ret = (LRESULT)TRUE;
|
||||
}
|
||||
}
|
||||
@ -1135,6 +1147,8 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
if (peer != NULL) {
|
||||
env->DeleteGlobalRef(peer);
|
||||
}
|
||||
tk.m_inputMethodData = ret;
|
||||
::SetEvent(tk.m_inputMethodWaitEvent);
|
||||
return ret;
|
||||
}
|
||||
case WM_AWT_HANDLE_NATIVE_IME_EVENT: {
|
||||
@ -1170,6 +1184,9 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
Changed to commit it according to the flag 10/29/98*/
|
||||
ImmNotifyIME((HIMC)wParam, NI_COMPOSITIONSTR,
|
||||
(lParam ? CPS_COMPLETE : CPS_CANCEL), 0);
|
||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||
tk.m_inputMethodData = 0;
|
||||
::SetEvent(tk.m_inputMethodWaitEvent);
|
||||
return 0;
|
||||
}
|
||||
case WM_AWT_SETCONVERSIONSTATUS: {
|
||||
@ -1177,12 +1194,18 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
DWORD smode;
|
||||
ImmGetConversionStatus((HIMC)wParam, (LPDWORD)&cmode, (LPDWORD)&smode);
|
||||
ImmSetConversionStatus((HIMC)wParam, (DWORD)LOWORD(lParam), smode);
|
||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||
tk.m_inputMethodData = 0;
|
||||
::SetEvent(tk.m_inputMethodWaitEvent);
|
||||
return 0;
|
||||
}
|
||||
case WM_AWT_GETCONVERSIONSTATUS: {
|
||||
DWORD cmode;
|
||||
DWORD smode;
|
||||
ImmGetConversionStatus((HIMC)wParam, (LPDWORD)&cmode, (LPDWORD)&smode);
|
||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||
tk.m_inputMethodData = cmode;
|
||||
::SetEvent(tk.m_inputMethodWaitEvent);
|
||||
return cmode;
|
||||
}
|
||||
case WM_AWT_ACTIVATEKEYBOARDLAYOUT: {
|
||||
@ -1217,6 +1240,9 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
// instead of LOWORD and HIWORD
|
||||
p->OpenCandidateWindow(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
env->DeleteGlobalRef(peerObject);
|
||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||
tk.m_inputMethodData = 0;
|
||||
::SetEvent(tk.m_inputMethodWaitEvent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1238,10 +1264,16 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
|
||||
|
||||
case WM_AWT_SETOPENSTATUS: {
|
||||
ImmSetOpenStatus((HIMC)wParam, (BOOL)lParam);
|
||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||
tk.m_inputMethodData = 0;
|
||||
::SetEvent(tk.m_inputMethodWaitEvent);
|
||||
return 0;
|
||||
}
|
||||
case WM_AWT_GETOPENSTATUS: {
|
||||
return (DWORD)ImmGetOpenStatus((HIMC)wParam);
|
||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||
tk.m_inputMethodData = (DWORD)ImmGetOpenStatus((HIMC)wParam);
|
||||
::SetEvent(tk.m_inputMethodWaitEvent);
|
||||
return tk.m_inputMethodData;
|
||||
}
|
||||
case WM_DISPLAYCHANGE: {
|
||||
// Reinitialize screens
|
||||
@ -3166,3 +3198,23 @@ BOOL AwtToolkit::TICloseTouchInputHandle(HTOUCHINPUT hTouchInput) {
|
||||
}
|
||||
return m_pCloseTouchInputHandle(hTouchInput);
|
||||
}
|
||||
|
||||
/*
|
||||
* The fuction intended for access to an IME API. It posts IME message to the queue and
|
||||
* waits untill the message processing is completed.
|
||||
*
|
||||
* On Windows 10 the IME may process the messages send via SenMessage() from other threads
|
||||
* when the IME is called by TranslateMessage(). This may cause an reentrancy issue when
|
||||
* the windows procedure processing the sent message call an IME function and leaves
|
||||
* the IME functionality in an unexpected state.
|
||||
* This function avoids reentrancy issue and must be used for sending of all IME messages
|
||||
* instead of SendMessage().
|
||||
*/
|
||||
LRESULT AwtToolkit::InvokeInputMethodFunction(UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
CriticalSection::Lock lock(m_inputMethodLock);
|
||||
if (PostMessage(msg, wParam, lParam)) {
|
||||
::WaitForSingleObject(m_inputMethodWaitEvent, INFINITE);
|
||||
return m_inputMethodData;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. 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
|
||||
@ -244,6 +244,8 @@ public:
|
||||
UINT cInputs, PTOUCHINPUT pInputs, int cbSize);
|
||||
BOOL TICloseTouchInputHandle(HTOUCHINPUT hTouchInput);
|
||||
|
||||
LRESULT InvokeInputMethodFunction(UINT msg, WPARAM wParam=0, LPARAM lParam=0);
|
||||
|
||||
INLINE BOOL localPump() { return m_localPump; }
|
||||
INLINE BOOL VerifyComponents() { return FALSE; } // TODO: Use new DebugHelper class to set this flag
|
||||
INLINE HWND GetHWnd() { return m_toolkitHWnd; }
|
||||
@ -498,6 +500,10 @@ private:
|
||||
HMODULE m_dllHandle; /* The module handle. */
|
||||
|
||||
CriticalSection m_Sync;
|
||||
CriticalSection m_inputMethodLock;
|
||||
|
||||
HANDLE m_inputMethodWaitEvent;
|
||||
LRESULT m_inputMethodData;
|
||||
|
||||
/* track display changes - used by palette-updating code.
|
||||
This is a workaround for a windows bug that prevents
|
||||
|
Loading…
Reference in New Issue
Block a user