8164143: Improve components for menu items
authorserb
Tue, 27 Sep 2016 03:23:40 +0300
changeset 43204 4358b67f2e5a
parent 43203 955e87b8f623
child 43205 df23cecb03ae
8164143: Improve components for menu items Reviewed-by: ssadetsky, prr, ddehaven
jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenu.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuBar.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuComponent.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuItem.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPopupMenu.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java
jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenu.m
jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m
jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuComponent.m
jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.h
jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java	Tue Sep 27 03:23:40 2016 +0300
@@ -123,7 +123,7 @@
         }
 
         // grab the pointer to the CMenuBar, and retain it in native
-        nativeSetDefaultMenuBar(((CMenuBar)peer).getModel());
+        ((CMenuBar) peer).execute(_AppMenuBarHandler::nativeSetDefaultMenuBar);
     }
 
     void setAboutMenuItemVisible(final boolean present) {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -26,29 +26,28 @@
 package sun.lwawt.macosx;
 
 import java.awt.CheckboxMenuItem;
-import java.awt.EventQueue;
 import java.awt.event.ItemEvent;
 import java.awt.peer.CheckboxMenuItemPeer;
 
 import sun.awt.SunToolkit;
 
 public class CCheckboxMenuItem extends CMenuItem implements CheckboxMenuItemPeer {
-    boolean fAutoToggle = true;
-    boolean fIsIndeterminate = false;
+    volatile boolean fAutoToggle = true;
+    volatile boolean fIsIndeterminate = false;
 
     private native void nativeSetState(long modelPtr, boolean state);
     private native void nativeSetIsCheckbox(long modelPtr);
 
-    CCheckboxMenuItem(CheckboxMenuItem target) {
+    CCheckboxMenuItem(final CheckboxMenuItem target) {
         super(target);
-        nativeSetIsCheckbox(getModel());
+        execute(this::nativeSetIsCheckbox);
         setState(target.getState());
     }
 
     // MenuItemPeer implementation
     @Override
-    public void setState(boolean state) {
-        nativeSetState(getModel(), state);
+    public void setState(final boolean state) {
+        execute(ptr -> nativeSetState(ptr, state));
     }
 
     public void handleAction(final boolean state) {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java	Tue Sep 27 03:23:40 2016 +0300
@@ -23,7 +23,6 @@
  * questions.
  */
 
-
 package sun.lwawt.macosx;
 
 /**
@@ -34,6 +33,7 @@
     private static native void nativeCFRelease(final long ptr, final boolean disposeOnAppKitThread);
 
     private final boolean disposeOnAppKitThread;
+    // TODO this pointer should be private and accessed via CFNativeAction class
     protected volatile long ptr;
 
     /**
@@ -70,8 +70,72 @@
         nativeCFRelease(oldPtr, disposeOnAppKitThread); // perform outside of the synchronized block
     }
 
+    /**
+     * The interface which allows to execute some native operations with
+     * assumption that the native pointer will be valid till the end.
+     */
+    public interface CFNativeAction {
+
+        /**
+         * The native operation should be called from this method.
+         *
+         * @param  ptr the pointer to the native data
+         */
+        void run(long ptr);
+    }
+
+    /**
+     * The interface which allows to execute some native operations and get a
+     * result with assumption that the native pointer will be valid till the
+     * end.
+     */
+    interface CFNativeActionGet {
+
+        /**
+         * The native operation should be called from this method.
+         *
+         * @param  ptr the pointer to the native data
+         * @return result of the native operation
+         */
+        long run(long ptr);
+    }
+
+    /**
+     * This is utility method which should be used instead of the direct access
+     * to the {@link #ptr}, because this method guaranteed that the pointer will
+     * not be zero and will be valid till the end of the operation.It is highly
+     * recomended to not use any external lock in action. If the current
+     * {@link #ptr} is {@code 0} then action will be ignored.
+     *
+     * @param  action The native operation
+     */
+    public final synchronized void execute(final CFNativeAction action) {
+        if (ptr != 0) {
+            action.run(ptr);
+        }
+    }
+
+    /**
+     * This is utility method which should be used instead of the direct access
+     * to the {@link #ptr}, because this method guaranteed that the pointer will
+     * not be zero and will be valid till the end of the operation. It is highly
+     * recomended to not use any external lock in action. If the current
+     * {@link #ptr} is {@code 0} then action will be ignored and {@code} is
+     * returned.
+     *
+     * @param  action the native operation
+     * @return result of the native operation, usually the native pointer to
+     *         some other data
+     */
+    final synchronized long executeGet(final CFNativeActionGet action) {
+        if (ptr != 0) {
+            return action.run(ptr);
+        }
+        return 0;
+    }
+
     @Override
-    protected void finalize() throws Throwable {
+    protected final void finalize() throws Throwable {
         dispose();
     }
 }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenu.java	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenu.java	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -25,7 +25,9 @@
 
 package sun.lwawt.macosx;
 
-import java.awt.*;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
 import java.awt.peer.MenuItemPeer;
 import java.awt.peer.MenuPeer;
 
@@ -37,7 +39,7 @@
 
     // This way we avoiding invocation of the setters twice
     @Override
-    protected void initialize(MenuItem target) {
+    protected final void initialize(MenuItem target) {
         setLabel(target.getLabel());
         setEnabled(target.isEnabled());
     }
@@ -57,52 +59,50 @@
     }
 
     @Override
-    protected long createModel() {
+    long createModel() {
         CMenuComponent parent = (CMenuComponent)
             LWCToolkit.targetToPeer(getTarget().getParent());
 
-        if (parent instanceof CMenu ||
-            parent instanceof CPopupMenu)
-        {
-            return nativeCreateSubMenu(parent.getModel());
-        } else if (parent instanceof CMenuBar) {
+        if (parent instanceof CMenu) {
+            return parent.executeGet(this::nativeCreateSubMenu);
+        }
+        if (parent instanceof CMenuBar) {
             MenuBar parentContainer = (MenuBar)getTarget().getParent();
             boolean isHelpMenu = parentContainer.getHelpMenu() == getTarget();
             int insertionLocation = ((CMenuBar)parent).getNextInsertionIndex();
-            return nativeCreateMenu(parent.getModel(),
-                                    isHelpMenu, insertionLocation);
-        } else {
-            throw new InternalError("Parent must be CMenu or CMenuBar");
+            return parent.executeGet(ptr -> nativeCreateMenu(ptr, isHelpMenu,
+                                                             insertionLocation));
         }
+        throw new InternalError("Parent must be CMenu or CMenuBar");
     }
 
     @Override
-    public void addItem(MenuItem item) {
+    public final void addItem(MenuItem item) {
         // Nothing to do here -- we added it when we created the
         // menu item's peer.
     }
 
     @Override
-    public void delItem(int index) {
-        nativeDeleteItem(getModel(), index);
+    public final void delItem(final int index) {
+        execute(ptr -> nativeDeleteItem(ptr, index));
     }
 
     @Override
-    public void setLabel(String label) {
-        nativeSetMenuTitle(getModel(), label);
+    public final void setLabel(final String label) {
+        execute(ptr->nativeSetMenuTitle(ptr, label));
         super.setLabel(label);
     }
 
     // Note that addSeparator is never called directly from java.awt.Menu,
     // though it is required in the MenuPeer interface.
     @Override
-    public void addSeparator() {
-        nativeAddSeparator(getModel());
+    public final void addSeparator() {
+        execute(this::nativeAddSeparator);
     }
 
     // Used by ScreenMenuBar to get to the native menu for event handling.
-    public long getNativeMenu() {
-        return nativeGetNSMenu(getModel());
+    public final long getNativeMenu() {
+        return executeGet(this::nativeGetNSMenu);
     }
 
     private native long nativeCreateMenu(long parentMenuPtr,
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuBar.java	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuBar.java	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -31,7 +31,7 @@
 
 import sun.awt.AWTAccessor;
 
-public class CMenuBar extends CMenuComponent implements MenuBarPeer {
+public final class CMenuBar extends CMenuComponent implements MenuBarPeer {
 
     private int nextInsertionIndex = -1;
 
@@ -40,14 +40,15 @@
     }
 
     @Override
-    protected long createModel() {
+    long createModel() {
         return nativeCreateMenuBar();
     }
 
     @Override
-    public void addHelpMenu(Menu m) {
-        CMenu cMenu = AWTAccessor.getMenuComponentAccessor().getPeer(m);
-        nativeSetHelpMenu(getModel(), cMenu.getModel());
+    public void addHelpMenu(final Menu m) {
+        final CMenu cMenu = AWTAccessor.getMenuComponentAccessor().getPeer(m);
+        execute(parentPtr -> cMenu.execute(
+                menuPtr -> nativeSetHelpMenu(parentPtr, menuPtr)));
     }
 
     public int getNextInsertionIndex() {
@@ -65,8 +66,8 @@
     }
 
     @Override
-    public void delMenu(int index) {
-        nativeDelMenu(getModel(), index);
+    public void delMenu(final int index) {
+        execute(ptr -> nativeDelMenu(ptr, index));
     }
 
     private native long nativeCreateMenuBar();
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuComponent.java	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuComponent.java	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -29,36 +29,32 @@
 import java.awt.MenuComponent;
 import java.awt.peer.MenuComponentPeer;
 
-public abstract class CMenuComponent implements MenuComponentPeer {
+abstract class CMenuComponent extends CFRetainedResource
+        implements MenuComponentPeer {
+
+    private final MenuComponent target;
 
-    private MenuComponent target;
-    private long modelPtr;
-
-    CMenuComponent(MenuComponent target) {
+    CMenuComponent(final MenuComponent target) {
+        super(0, true);
         this.target = target;
-        this.modelPtr = createModel();
+        setPtr(createModel());
     }
 
-    MenuComponent getTarget() {
+    final MenuComponent getTarget() {
         return target;
     }
 
-    public long getModel() {
-        return modelPtr;
+    abstract long createModel();
+
+    @Override
+    public final void dispose() {
+        super.dispose();
+        LWCToolkit.targetDisposedPeer(target, this);
     }
 
-    protected abstract long createModel();
-
-    public void dispose() {
-        LWCToolkit.targetDisposedPeer(target, this);
-        nativeDispose(modelPtr);
-        target = null;
-    }
-
-    private native void nativeDispose(long modelPtr);
-
     // 1.5 peer method
-    public void setFont(Font f) {
+    @Override
+    public final void setFont(final Font f) {
         // no-op, as we don't currently support menu fonts
         // c.f. radar 4032912
     }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuItem.java	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuItem.java	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -25,16 +25,17 @@
 
 package sun.lwawt.macosx;
 
+import java.awt.MenuItem;
+import java.awt.MenuShortcut;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.peer.MenuItemPeer;
+import java.util.concurrent.atomic.AtomicBoolean;
+
 import sun.awt.SunToolkit;
 import sun.lwawt.LWToolkit;
 
-import java.awt.MenuContainer;
-import java.awt.MenuItem;
-import java.awt.MenuShortcut;
-import java.awt.event.*;
-import java.awt.peer.MenuItemPeer;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 public class CMenuItem extends CMenuComponent implements MenuItemPeer {
 
     private final AtomicBoolean enabled = new AtomicBoolean(true);
@@ -58,9 +59,9 @@
     }
 
     @Override
-    protected long createModel() {
+    long createModel() {
         CMenuComponent parent = (CMenuComponent)LWToolkit.targetToPeer(getTarget().getParent());
-        return nativeCreate(parent.getModel(), isSeparator());
+        return parent.executeGet(ptr->nativeCreate(ptr, isSeparator()));
     }
 
     public void setLabel(String label, char keyChar, int keyCode, int modifiers) {
@@ -90,7 +91,12 @@
             keyChar = 0;
         }
 
-        nativeSetLabel(getModel(), label, keyChar, keyCode, keyMask);
+        final String finalLabel = label;
+        final char finalKeyChar = keyChar;
+        final int finalKeyCode = keyCode;
+        final int finalKeyMask = keyMask;
+        execute(ptr -> nativeSetLabel(ptr, finalLabel, finalKeyChar,
+                                      finalKeyCode, finalKeyMask));
     }
 
     @Override
@@ -105,16 +111,16 @@
      * There isn't a need to expose this except in a instanceof because
      * it isn't defined in the peer api.
      */
-    public void setImage(java.awt.Image img) {
+    public final void setImage(final java.awt.Image img) {
         CImage cimg = CImage.getCreator().createFromImage(img);
-        nativeSetImage(getModel(), cimg == null ? 0L : cimg.ptr);
+        execute(ptr -> nativeSetImage(ptr, cimg == null ? 0L : cimg.ptr));
     }
 
     /**
      * New API for tooltips
      */
-    public void setToolTipText(String text) {
-        nativeSetTooltip(getModel(), text);
+    public final void setToolTipText(final String text) {
+        execute(ptr -> nativeSetTooltip(ptr, text));
     }
 
 //    @Override
@@ -138,7 +144,8 @@
             b &= ((CMenuItem) parent).isEnabled();
         }
         if (enabled.compareAndSet(!b, b)) {
-            nativeSetEnabled(getModel(), b);
+            final boolean finalB = b;
+            execute(ptr->nativeSetEnabled(ptr, finalB));
         }
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Tue Sep 27 03:23:40 2016 +0300
@@ -449,7 +449,7 @@
         final long nsWindowPtr = getNSWindowPtr();
         CMenuBar mbPeer = (CMenuBar)LWToolkit.targetToPeer(mb);
         if (mbPeer != null) {
-            nativeSetNSWindowMenuBar(nsWindowPtr, mbPeer.getModel());
+            mbPeer.execute(ptr -> nativeSetNSWindowMenuBar(nsWindowPtr, ptr));
         } else {
             nativeSetNSWindowMenuBar(nsWindowPtr, 0);
         }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPopupMenu.java	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPopupMenu.java	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -25,18 +25,20 @@
 
 package sun.lwawt.macosx;
 
-import java.awt.*;
+import java.awt.Component;
+import java.awt.Event;
+import java.awt.Point;
+import java.awt.PopupMenu;
 import java.awt.peer.PopupMenuPeer;
 
-import sun.lwawt.LWWindowPeer;
+final class CPopupMenu extends CMenu implements PopupMenuPeer {
 
-public class CPopupMenu extends CMenu implements PopupMenuPeer {
     CPopupMenu(PopupMenu target) {
         super(target);
     }
 
     @Override
-    protected long createModel() {
+    long createModel() {
         return nativeCreatePopupMenu();
     }
 
@@ -50,7 +52,7 @@
             Point loc = origin.getLocationOnScreen();
             e.x += loc.x;
             e.y += loc.y;
-            nativeShowPopupMenu(getModel(), e.x, e.y);
+            execute(ptr -> nativeShowPopupMenu(ptr, e.x, e.y));
         }
     }
 }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -118,7 +118,10 @@
             }
         }
 
-        return checkAndCreatePopupPeer().getModel();
+        // This method is executed on Appkit, so if ptr is not zero means that,
+        // it is still not deallocated(even if we call NSApp postRunnableEvent)
+        // and sent CFRelease to the native queue
+        return checkAndCreatePopupPeer().ptr;
     }
 
     /**
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenu.m	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenu.m	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -38,7 +38,7 @@
 - (id)initWithPeer:(jobject)peer {
 AWT_ASSERT_APPKIT_THREAD;
     // Create the new NSMenu
-    self = [super initWithPeer:peer asSeparator:[NSNumber numberWithBool:NO]];
+    self = [super initWithPeer:peer asSeparator:NO];
     if (self) {
         fMenu = [NSMenu javaMenuWithTitle:@""];
         [fMenu retain];
@@ -133,14 +133,13 @@
 
 CMenu * createCMenu (jobject cPeerObjGlobal) {
 
-    CMenu *aCMenu = nil;
+    __block CMenu *aCMenu = nil;
+
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
 
-    // We use an array here only to be able to get a return value
-    NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], nil];
-
-    [ThreadUtilities performOnMainThread:@selector(_create_OnAppKitThread:) on:[CMenu alloc] withObject:args waitUntilDone:YES];
-
-    aCMenu = (CMenu *)[args objectAtIndex: 0];
+        aCMenu = [[CMenu alloc] initWithPeer:cPeerObjGlobal];
+        // the aCMenu is released in CMenuComponent.dispose()
+    }];
 
     if (aCMenu == nil) {
         return 0L;
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuBar.m	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -383,27 +383,20 @@
 Java_sun_lwawt_macosx_CMenuBar_nativeCreateMenuBar
     (JNIEnv *env, jobject peer)
 {
-    CMenuBar *aCMenuBar = nil;
+    __block CMenuBar *aCMenuBar = nil;
     JNF_COCOA_ENTER(env);
 
     jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);
 
-    // We use an array here only to be able to get a return value
-    NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], nil];
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
 
-    [ThreadUtilities performOnMainThread:@selector(_create_OnAppKitThread:) on:[CMenuBar alloc] withObject:args waitUntilDone:YES];
-
-    aCMenuBar = (CMenuBar *)[args objectAtIndex: 0];
-
+        aCMenuBar = [[CMenuBar alloc] initWithPeer:cPeerObjGlobal];
+        // the aCMenuBar is released in CMenuComponent.dispose()
+    }];
     if (aCMenuBar == nil) {
         return 0L;
     }
 
-    // [args release];
-
-    // A strange memory managment after that.
-
-
     JNF_COCOA_EXIT(env);
     return ptr_to_jlong(aCMenuBar);
 }
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuComponent.m	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuComponent.m	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -41,45 +41,11 @@
     return self;
 }
 
--(void) cleanup {
-    // Used by subclasses
-}
-
--(void) disposer {
+- (void)dealloc {
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
     JNFDeleteGlobalRef(env, fPeer);
     fPeer = NULL;
 
-    [self cleanup];
-    [self release];
+    [super dealloc];
 }
-
-// The method is used by all subclasses, since the process of the creation
-// is the same. The only exception is the CMenuItem class.
-- (void) _create_OnAppKitThread: (NSMutableArray *)argValue {
-    jobject cPeerObjGlobal = (jobject)[[argValue objectAtIndex: 0] pointerValue];
-    CMenuItem *aCMenuItem = [self initWithPeer:cPeerObjGlobal];
-    [argValue removeAllObjects];
-    [argValue addObject: aCMenuItem];
-}
-
 @end
-
-/*
- * Class:     sun_lwawt_macosx_CMenuComponent
- * Method:    nativeDispose
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL
-Java_sun_lwawt_macosx_CMenuComponent_nativeDispose
-(JNIEnv *env, jobject peer, jlong menuItemObj)
-{
-JNF_COCOA_ENTER(env);
-
-    [ThreadUtilities performOnMainThread:@selector(disposer)
-                                      on:((id)jlong_to_ptr(menuItemObj))
-                              withObject:nil
-                           waitUntilDone:NO];
-
-JNF_COCOA_EXIT(env);
-}
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.h	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.h	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -32,7 +32,7 @@
 }
 
 // Setup
-- (id) initWithPeer:(jobject)peer asSeparator: (NSNumber *) asSeparator;
+- (id) initWithPeer:(jobject)peer asSeparator: (BOOL) asSeparator;
 - (void) setIsCheckbox;
 
 // Events
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m	Thu Sep 15 13:24:24 2016 +0530
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m	Tue Sep 27 03:23:40 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -39,11 +39,11 @@
 
 @implementation CMenuItem
 
-- (id) initWithPeer:(jobject)peer asSeparator: (NSNumber *) asSeparator{
+- (id) initWithPeer:(jobject)peer asSeparator: (BOOL) asSeparator{
     AWT_ASSERT_APPKIT_THREAD;
     self = [super initWithPeer:peer];
     if (self) {
-        if ([asSeparator boolValue]) {
+        if (asSeparator) {
             fMenuItem = (NSMenuItem*)[NSMenuItem separatorItem];
             [fMenuItem retain];
         } else {
@@ -204,12 +204,9 @@
     }];
 }
 
-- (void)cleanup {
+- (void)dealloc {
     [fMenuItem setAction:NULL];
     [fMenuItem setTarget:nil];
-}
-
-- (void)dealloc {
     [fMenuItem release];
     fMenuItem = nil;
     
@@ -228,14 +225,6 @@
     fIsCheckbox = YES;
 }
 
-- (void) _createMenuItem_OnAppKitThread: (NSMutableArray *)argValue {
-    jobject cPeerObjGlobal = (jobject)[[argValue objectAtIndex: 0] pointerValue];
-    NSNumber * asSeparator = (NSNumber *)[argValue objectAtIndex: 1];
-    CMenuItem *aCMenuItem = [self initWithPeer: cPeerObjGlobal asSeparator: asSeparator];
-    [argValue removeAllObjects];
-    [argValue addObject: aCMenuItem];
-}
-
 - (NSString *)description {
     return [NSString stringWithFormat:@"CMenuItem[ %@ ]", fMenuItem];
 }
@@ -397,24 +386,18 @@
 (JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator)
 {
     
-    CMenuItem *aCMenuItem = nil;
+    __block CMenuItem *aCMenuItem = nil;
+    BOOL asSeparator = (isSeparator == JNI_TRUE) ? YES: NO;
     CMenu *parentCMenu = (CMenu *)jlong_to_ptr(parentCMenuObj);
     JNF_COCOA_ENTER(env);
     
     jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);
-    
-    NSMutableArray *args = nil;
-    
-    // Create a new item....
-    if (isSeparator == JNI_TRUE) {
-        args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:YES],  nil];
-    } else {
-        args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:NO],  nil];
-    }
-    
-    [ThreadUtilities performOnMainThread:@selector(_createMenuItem_OnAppKitThread:) on:[CMenuItem alloc] withObject:args waitUntilDone:YES];
-    
-    aCMenuItem = (CMenuItem *)[args objectAtIndex: 0];
+
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+        aCMenuItem = [[CMenuItem alloc] initWithPeer: cPeerObjGlobal
+                                         asSeparator: asSeparator];
+        // the CMenuItem is released in CMenuComponent.dispose()
+    }];
     
     if (aCMenuItem == nil) {
         return 0L;