Fixed race condition between bind() and add(), where they could both add

an entry. Now entries will only be added if they have not already been
 added.
This commit is contained in:
nathan 2017-07-04 19:09:21 +02:00
parent 44c5b11816
commit 133cb9f8f8
3 changed files with 19 additions and 7 deletions

View File

@ -56,6 +56,14 @@ class Entry {
// END methods for hooking into the system tray, menu's, and entries.
/**
* @return true if this entry has a peer assigned to it.
*/
public final
boolean hasPeer() {
return peer != null;
}
/**
* @return the parent menu (of this entry or menu) or null if we are the root menu
*/

View File

@ -124,7 +124,6 @@ class Menu extends MenuItem {
copy = new ArrayList<Entry>(menuEntries);
}
for (int i = 0, menuEntriesSize = copy.size(); i < menuEntriesSize; i++) {
final Entry menuEntry = copy.get(i);
peer.add(this, menuEntry, i);
@ -145,7 +144,6 @@ class Menu extends MenuItem {
@SuppressWarnings("Duplicates")
public final
Menu add(final JMenu entry) {
Menu menu = new Menu();
menu.setEnabled(entry.isEnabled());
@ -267,7 +265,7 @@ class Menu extends MenuItem {
* Adds a menu entry, separator, or sub-menu to this menu.
*/
public
<T extends Entry> T add(final T entry, int index) {
<T extends Entry> T add(final T entry, int index) {
synchronized (menuEntries) {
// access on this object must be synchronized for object visibility
if (index == -1) {
@ -279,10 +277,10 @@ class Menu extends MenuItem {
}
menuEntries.add(index, entry);
}
}
if (peer != null) {
((MenuPeer) peer).add(this, entry, index);
if (peer != null) {
((MenuPeer) peer).add(this, entry, index);
}
}
return entry;
@ -351,7 +349,7 @@ class Menu extends MenuItem {
}
/**
* This removes a menu entry from the dropdown menu.
* This removes a menu entry from the menu.
*
* @param entry This is the menu entry to remove
*/

View File

@ -73,6 +73,12 @@ class SwingMenu implements MenuPeer {
@Override
public
void run() {
// don't add this entry if it's already been added via another method. Because of threading via swing/gtk, entries can
// POSSIBLY get added twice. Once via add() and once via bind().
if (entry.hasPeer()) {
return;
}
if (entry instanceof Menu) {
SwingMenu swingMenu = new SwingMenu(SwingMenu.this, (Menu) entry);
((Menu) entry).bind(swingMenu, parentMenu, parentMenu.getSystemTray());