OpenJDK / jdk / hs
changeset 44754:cc5c1fb080a3
8167110: Windows peering issue
Reviewed-by: ssadetsky, mschoene, prr
line wrap: on
line diff
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java Sat Nov 19 13:10:18 2016 +0300 @@ -71,7 +71,7 @@ enable(false); } - public void readShortcutLabel() { + private void readShortcutLabel() { //Fix for 6288578: PIT. Windows: Shortcuts displayed for the menuitems in a popup menu WMenuPeer ancestor = parent; while (ancestor != null && !(ancestor instanceof WMenuBarPeer)) { @@ -115,7 +115,7 @@ readShortcutLabel(); } - protected void checkMenuCreation() + void checkMenuCreation() { // fix for 5088782: check if menu peer is created successfully if (pData == 0)
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java Sat Nov 19 13:10:18 2016 +0300 @@ -36,14 +36,14 @@ // The Windows handle for the native widget. volatile long pData; // if the native peer has been destroyed - volatile boolean destroyed = false; + private volatile boolean destroyed; // The associated AWT object. - Object target; + volatile Object target; private volatile boolean disposed; // set from JNI if any errors in creating the peer occur - protected Error createError = null; + volatile Error createError = null; // used to synchronize the state of this peer private final Object stateLock = new Object();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp Sat Nov 19 13:10:18 2016 +0300 @@ -4220,7 +4220,7 @@ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); if (drawInfo.CtlType == ODT_MENU) { - if (drawInfo.itemData != 0) { + if (IsMenu((HMENU)drawInfo.hwndItem) && drawInfo.itemData != 0) { AwtMenu* menu = (AwtMenu*)(drawInfo.itemData); menu->DrawItem(drawInfo); }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Menu.cpp Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Menu.cpp Sat Nov 19 13:10:18 2016 +0300 @@ -34,6 +34,13 @@ /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. */ +/***********************************************************************/ +// struct for _DelItem() method +struct DelItemStruct { + jobject menuitem; + jint index; +}; + /************************************************************************ * AwtMenuItem fields */ @@ -64,7 +71,6 @@ ::DestroyMenu(m_hMenu); m_hMenu = NULL; } - AwtMenuItem::Dispose(); } @@ -73,7 +79,7 @@ } /* Create a new AwtMenu object and menu. */ -AwtMenu* AwtMenu::Create(jobject self, AwtMenu* parentMenu) +AwtMenu* AwtMenu::Create(jobject self, jobject parent) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -85,6 +91,9 @@ return NULL; } + JNI_CHECK_NULL_GOTO(parent, "peer", done); + AwtMenu* parentMenu = (AwtMenu*) JNI_GET_PDATA(parent); + target = env->GetObjectField(self, AwtObject::targetID); JNI_CHECK_NULL_GOTO(target, "null target", done); @@ -119,6 +128,46 @@ return menu; } +void AwtMenu::_AddSeparator(void *param) +{ + if (AwtToolkit::IsMainThread()) { + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + + jobject self = (jobject)param; + AwtMenu *m = NULL; + PDATA pData; + JNI_CHECK_PEER_GOTO(self, ret); + m = (AwtMenu *)pData; + m->AddSeparator(); +ret: + env->DeleteGlobalRef(self); + } else { + AwtToolkit::GetInstance().InvokeFunction(AwtMenu::_AddSeparator, param); + } +} + +void AwtMenu::_DelItem(void *param) +{ + if (AwtToolkit::IsMainThread()) { + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + + DelItemStruct *dis = (DelItemStruct*) param; + jobject self = dis->menuitem; + jint index = dis->index; + + AwtMenu *m = NULL; + PDATA pData; + JNI_CHECK_PEER_GOTO(self, ret); + m = (AwtMenu *)pData; + m->DeleteItem(static_cast<UINT>(index)); +ret: + env->DeleteGlobalRef(self); + delete dis; + } else { + AwtToolkit::GetInstance().InvokeFunction(AwtMenu::_DelItem, param); + } +} + void AwtMenu::UpdateLayout() { UpdateLayout(GetHMenu()); @@ -323,24 +372,6 @@ return (GetMenuBar() == GetMenuContainer()); } -LRESULT AwtMenu::WinThreadExecProc(ExecuteArgs * args) -{ - switch( args->cmdId ) { - case MENU_ADDSEPARATOR: - this->AddSeparator(); - break; - - case MENU_DELITEM: - this->DeleteItem(static_cast<UINT>(args->param1)); - break; - - default: - AwtMenuItem::WinThreadExecProc(args); - break; - } - return 0L; -} - /************************************************************************ * WMenuPeer native methods */ @@ -382,15 +413,14 @@ { TRY; - PDATA pData; - JNI_CHECK_PEER_RETURN(self); + jobject selfGlobalRef = env->NewGlobalRef(self); - AwtObject::WinThreadExec(self, AwtMenu::MENU_ADDSEPARATOR); + AwtToolkit::GetInstance().SyncCall(AwtMenu::_AddSeparator, selfGlobalRef); + // selfGlobalRef is deleted in _AddSeparator CATCH_BAD_ALLOC; } - /* * Class: sun_awt_windows_WMenuPeer * Method: delItem @@ -402,10 +432,12 @@ { TRY; - PDATA pData; - JNI_CHECK_PEER_RETURN(self); + DelItemStruct *dis = new DelItemStruct; + dis->menuitem = env->NewGlobalRef(self); + dis->index = index; - AwtObject::WinThreadExec(self, AwtMenu::MENU_DELITEM, index); + AwtToolkit::GetInstance().SyncCall(AwtMenu::_DelItem, dis); + // global refs and dis are deleted in _DelItem CATCH_BAD_ALLOC; } @@ -421,13 +453,8 @@ { TRY; - PDATA pData; - JNI_CHECK_PEER_RETURN(menuBar); - - AwtMenuBar* awtMenuBar = (AwtMenuBar *)pData; - AwtToolkit::CreateComponent(self, awtMenuBar, - (AwtToolkit::ComponentFactory)AwtMenu::Create,FALSE); - JNI_CHECK_PEER_CREATION_RETURN(self); + AwtToolkit::CreateComponent(self, menuBar, + (AwtToolkit::ComponentFactory)AwtMenu::Create); CATCH_BAD_ALLOC; } @@ -443,13 +470,8 @@ { TRY; - PDATA pData; - JNI_CHECK_PEER_RETURN(menu); - - AwtMenu* awtMenu = (AwtMenu *)pData; - AwtToolkit::CreateComponent(self, awtMenu, - (AwtToolkit::ComponentFactory)AwtMenu::Create,FALSE); - JNI_CHECK_PEER_CREATION_RETURN(self); + AwtToolkit::CreateComponent(self, menu, + (AwtToolkit::ComponentFactory)AwtMenu::Create); CATCH_BAD_ALLOC; }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Menu.h Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Menu.h Sat Nov 19 13:10:18 2016 +0300 @@ -42,13 +42,6 @@ class AwtMenu : public AwtMenuItem { public: - // id's for methods executed on toolkit thread - enum { - MENU_ADDSEPARATOR = MENUITEM_LAST+1, - MENU_DELITEM, - MENU_LAST - }; - /* method ids for java.awt.Menu */ static jmethodID countItemsMID; static jmethodID getItemMID; @@ -61,7 +54,7 @@ virtual LPCTSTR GetClassName(); /* Create a new AwtMenu. This must be run on the main thread. */ - static AwtMenu* Create(jobject self, AwtMenu* parentMenu); + static AwtMenu* Create(jobject self, jobject parent); INLINE HMENU GetHMenu() { return m_hMenu; } INLINE void SetHMenu(HMENU hMenu) { @@ -94,9 +87,9 @@ void MeasureItem(HDC hDC, MEASUREITEMSTRUCT& measureInfo); void MeasureItems(HDC hDC, MEASUREITEMSTRUCT& measureInfo); - virtual LRESULT WinThreadExecProc(ExecuteArgs * args); - // invoked on Toolkit thread + static void _AddSeparator(void *param); + static void _DelItem(void *param); static void _CreateMenu(void *param); static void _CreateSubMenu(void *param); virtual BOOL IsSeparator() { return FALSE; }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp Sat Nov 19 13:10:18 2016 +0300 @@ -30,6 +30,12 @@ */ /***********************************************************************/ +// struct for _DelItem() method +struct DelItemStruct { + jobject menuitem; + jint index; +}; +/***********************************************************************/ // struct for _AddMenu() method struct AddMenuStruct { jobject menubar; @@ -130,18 +136,6 @@ return myFrame->GetHWnd(); } -void AwtMenuBar::SendDrawItem(AwtMenuItem* awtMenuItem, - DRAWITEMSTRUCT& drawInfo) -{ - awtMenuItem->DrawItem(drawInfo); -} - -void AwtMenuBar::SendMeasureItem(AwtMenuItem* awtMenuItem, - HDC hDC, MEASUREITEMSTRUCT& measureInfo) -{ - awtMenuItem->MeasureItem(hDC, measureInfo); -} - int AwtMenuBar::CountItem(jobject menuBar) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -164,9 +158,9 @@ jobject menuItemPeer = GetPeerForTarget(env, menu); PDATA pData; + AwtMenuItem* awtMenuItem = NULL; JNI_CHECK_PEER_GOTO(menuItemPeer, done); - - AwtMenuItem* awtMenuItem = (AwtMenuItem*)pData; + awtMenuItem = (AwtMenuItem*)pData; done: env->DeleteLocalRef(menu); @@ -215,20 +209,6 @@ VERIFY(::DrawMenuBar(GetOwnerHWnd())); } -LRESULT AwtMenuBar::WinThreadExecProc(ExecuteArgs * args) -{ - switch( args->cmdId ) { - case MENUBAR_DELITEM: - this->DeleteItem(static_cast<UINT>(args->param1)); - break; - - default: - AwtMenu::WinThreadExecProc(args); - break; - } - return 0L; -} - void AwtMenuBar::_AddMenu(void *param) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -257,6 +237,28 @@ delete ams; } +void AwtMenuBar::_DelItem(void *param) +{ + if (AwtToolkit::IsMainThread()) { + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + + DelItemStruct *dis = (DelItemStruct*) param; + jobject self = dis->menuitem; + jint index = dis->index; + + AwtMenuBar *m = NULL; + PDATA pData; + JNI_CHECK_PEER_GOTO(self, ret); + m = (AwtMenuBar *)pData; + m->DeleteItem(static_cast<UINT>(index)); +ret: + env->DeleteGlobalRef(self); + delete dis; + } else { + AwtToolkit::GetInstance().InvokeFunction(AwtMenuBar::_DelItem, param); + } +} + /************************************************************************ * MenuBar native methods */ @@ -325,9 +327,12 @@ { TRY; - PDATA pData; - JNI_CHECK_PEER_RETURN(self); - AwtObject::WinThreadExec(self, AwtMenuBar::MENUBAR_DELITEM, (LPARAM)index); + DelItemStruct *dis = new DelItemStruct; + dis->menuitem = env->NewGlobalRef(self); + dis->index = index; + + AwtToolkit::GetInstance().SyncCall(AwtMenuBar::_DelItem, dis); + // global refs and dis are deleted in _DelItem CATCH_BAD_ALLOC; } @@ -346,9 +351,6 @@ AwtToolkit::CreateComponent(self, frame, (AwtToolkit::ComponentFactory) AwtMenuBar::Create); - PDATA pData; - JNI_CHECK_PEER_CREATION_RETURN(self); - CATCH_BAD_ALLOC; }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h Sat Nov 19 13:10:18 2016 +0300 @@ -42,10 +42,6 @@ class AwtMenuBar : public AwtMenu { public: - // id's for methods executed on toolkit thread - enum MenuExecIds { - MENUBAR_DELITEM = MENU_LAST+1 - }; /* java.awt.MenuBar method ids */ static jmethodID getMenuCountMID; @@ -73,20 +69,15 @@ AwtMenuItem* GetItem(jobject target, long index); int CountItem(jobject menuBar); - void SendDrawItem(AwtMenuItem* awtMenuItem, - DRAWITEMSTRUCT& drawInfo); - void SendMeasureItem(AwtMenuItem* awtMenuItem, - HDC hDC, MEASUREITEMSTRUCT& measureInfo); void DrawItem(DRAWITEMSTRUCT& drawInfo); void MeasureItem(HDC hDC, MEASUREITEMSTRUCT& measureInfo); void AddItem(AwtMenuItem* item); void DeleteItem(UINT index); - virtual LRESULT WinThreadExecProc(ExecuteArgs * args); - // called on Toolkit thread static void _AddMenu(void *param); + static void _DelItem(void *param); protected: AwtFrame* m_frame; };
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp Sat Nov 19 13:10:18 2016 +0300 @@ -50,6 +50,16 @@ jobject menuitem; jstring label; }; +// struct for _SetEnable() method +struct SetEnableStruct { + jobject menuitem; + jboolean isEnabled; +}; +// struct for _setState() method +struct SetStateStruct { + jobject menuitem; + jboolean isChecked; +}; /************************************************************************ * AwtMenuItem fields */ @@ -104,6 +114,7 @@ { if (m_freeId) { AwtToolkit::GetInstance().RemoveCmdID( GetID() ); + m_freeId = FALSE; } } void AwtMenuItem::Dispose() @@ -206,13 +217,12 @@ if (env->EnsureLocalCapacity(1) < 0) { return NULL; } - PDATA pData; - JNI_CHECK_PEER_RETURN_NULL(menuPeer); + JNI_CHECK_NULL_RETURN_NULL(menuPeer, "peer"); /* target is a java.awt.MenuItem */ target = env->GetObjectField(peer, AwtObject::targetID); - AwtMenu* menu = (AwtMenu *)pData; + AwtMenu* menu = (AwtMenu *)JNI_GET_PDATA(menuPeer); item = new AwtMenuItem(); jboolean isCheckbox = (jboolean)env->GetBooleanField(peer, AwtMenuItem::isCheckboxID); @@ -223,7 +233,9 @@ item->LinkObjects(env, peer); item->SetMenuContainer(menu); item->SetNewID(); - menu->AddItem(item); + if (menu != NULL) { + menu->AddItem(item); + } } catch (...) { env->DeleteLocalRef(target); throw; @@ -764,30 +776,6 @@ } } -LRESULT AwtMenuItem::WinThreadExecProc(ExecuteArgs * args) -{ - switch( args->cmdId ) { - case MENUITEM_ENABLE: - { - BOOL isEnabled = (BOOL)args->param1; - this->Enable(isEnabled); - } - break; - - case MENUITEM_SETSTATE: - { - BOOL isChecked = (BOOL)args->param1; - this->SetState(isChecked); - } - break; - - default: - AwtObject::WinThreadExecProc(args); - break; - } - return 0L; -} - void AwtMenuItem::_SetLabel(void *param) { if (AwtToolkit::IsMainThread()) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -887,6 +875,53 @@ } } +void AwtMenuItem::_SetEnable(void *param) +{ + if (AwtToolkit::IsMainThread()) { + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + + SetEnableStruct *ses = (SetEnableStruct*) param; + jobject self = ses->menuitem; + jboolean isEnabled = ses->isEnabled; + + AwtMenuItem *m = NULL; + + PDATA pData; + JNI_CHECK_PEER_GOTO(self, ret); + + m = (AwtMenuItem *)pData; + + m->Enable(isEnabled); +ret: + env->DeleteGlobalRef(self); + delete ses; + } else { + AwtToolkit::GetInstance().InvokeFunction(AwtMenuItem::_SetEnable, param); + } +} + +void AwtMenuItem::_SetState(void *param) +{ + if (AwtToolkit::IsMainThread()) { + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + + SetStateStruct *sts = (SetStateStruct*) param; + jobject self = sts->menuitem; + jboolean isChecked = sts->isChecked; + + AwtMenuItem *m = NULL; + + PDATA pData; + JNI_CHECK_PEER_GOTO(self, ret); + m = (AwtMenuItem *)pData; + m->SetState(isChecked); +ret: + env->DeleteGlobalRef(self); + delete sts; + } else { + AwtToolkit::GetInstance().InvokeFunction(AwtMenuItem::_SetState, param); + } +} BOOL AwtMenuItem::IsSeparator() { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); if (env->EnsureLocalCapacity(2) < 0) { @@ -1050,13 +1085,9 @@ { TRY; - JNI_CHECK_NULL_RETURN(menu, "null Menu"); AwtToolkit::CreateComponent(self, menu, (AwtToolkit::ComponentFactory) AwtMenuItem::Create); - PDATA pData; - JNI_CHECK_PEER_CREATION_RETURN(self); - CATCH_BAD_ALLOC; } @@ -1071,9 +1102,12 @@ { TRY; - PDATA pData; - JNI_CHECK_PEER_RETURN(self); - AwtObject::WinThreadExec(self, AwtMenuItem::MENUITEM_ENABLE, (LPARAM)on ); + SetEnableStruct *ses = new SetEnableStruct; + ses->menuitem = env->NewGlobalRef(self); + ses->isEnabled = on; + + AwtToolkit::GetInstance().SyncCall(AwtMenuItem::_SetEnable, ses); + // global refs and ses are deleted in _SetEnable CATCH_BAD_ALLOC; } @@ -1112,9 +1146,12 @@ { TRY; - PDATA pData; - JNI_CHECK_PEER_RETURN(self); - AwtObject::WinThreadExec(self, AwtMenuItem::MENUITEM_SETSTATE, (LPARAM)on); + SetStateStruct *sts = new SetStateStruct; + sts->menuitem = env->NewGlobalRef(self); + sts->isChecked = on; + + AwtToolkit::GetInstance().SyncCall(AwtMenuItem::_SetState, sts); + // global refs and sts are deleted in _SetState CATCH_BAD_ALLOC; }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.h Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.h Sat Nov 19 13:10:18 2016 +0300 @@ -45,13 +45,6 @@ class AwtMenuItem : public AwtObject { public: - // id's for methods executed on toolkit thread - enum { - MENUITEM_ENABLE, - MENUITEM_SETSTATE, - MENUITEM_LAST - }; - /* java.awt.MenuComponent fields */ static jfieldID fontID; static jfieldID appContextID; @@ -154,13 +147,14 @@ */ MsgRouting WmNotify(UINT notifyCode); - virtual LRESULT WinThreadExecProc(ExecuteArgs * args); virtual BOOL IsDisabledAndPopup() { return FALSE; } virtual BOOL IsSeparator(); // invoked on Toolkit thread + static void _SetState(void *param); + static void _SetEnable(void *param); static void _SetLabel(void *param); static void _UpdateLayout(void *param);
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_PopupMenu.cpp Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_PopupMenu.cpp Sat Nov 19 13:10:18 2016 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -65,7 +65,7 @@ } /* Create a new AwtPopupMenu object and menu. */ -AwtPopupMenu* AwtPopupMenu::Create(jobject self, AwtComponent* parent) +AwtPopupMenu* AwtPopupMenu::Create(jobject self, jobject parent) { JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -77,6 +77,9 @@ return NULL; } + JNI_CHECK_NULL_GOTO(parent, "peer", done); + AwtComponent* awtParent = (AwtComponent*) JNI_GET_PDATA(parent); + target = env->GetObjectField(self, AwtObject::targetID); JNI_CHECK_NULL_GOTO(target, "null target", done); @@ -94,7 +97,7 @@ popupMenu->SetHMenu(hMenu); popupMenu->LinkObjects(env, self); - popupMenu->SetParent(parent); + popupMenu->SetParent(awtParent); } catch (...) { env->DeleteLocalRef(target); throw; @@ -274,12 +277,8 @@ { TRY; - PDATA pData; - JNI_CHECK_PEER_RETURN(parent); - AwtComponent* awtParent = (AwtComponent *)pData; AwtToolkit::CreateComponent( - self, awtParent, (AwtToolkit::ComponentFactory)AwtPopupMenu::Create, FALSE); - JNI_CHECK_PEER_CREATION_RETURN(self); + self, parent, (AwtToolkit::ComponentFactory)AwtPopupMenu::Create); CATCH_BAD_ALLOC; }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_PopupMenu.h Thu Oct 20 15:10:52 2016 +0100 +++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_PopupMenu.h Sat Nov 19 13:10:18 2016 +0300 @@ -47,7 +47,7 @@ virtual LPCTSTR GetClassName(); /* Create a new AwtPopupMenu. This must be run on the main thread. */ - static AwtPopupMenu* Create(jobject self, AwtComponent* parent); + static AwtPopupMenu* Create(jobject self, jobject parent); /* Display the popup modally. */ void Show(JNIEnv *env, jobject event, BOOL isTrayIconPopup);