From 7eb3d26af7fc3f2bee5bac0c51f2ef0ad27f7d97 Mon Sep 17 00:00:00 2001 From: nathan Date: Sun, 16 Nov 2014 15:27:54 +0100 Subject: [PATCH] Fixed race condition issue when starting up GTK trays. Changed exectutor service to shutdown on removeTray --- src/dorkbox/util/tray/SystemTray.java | 9 ++++++--- src/dorkbox/util/tray/linux/AppIndicatorTray.java | 15 +++++++++++++-- src/dorkbox/util/tray/linux/GtkSystemTray.java | 14 +++++++++++++- src/dorkbox/util/tray/swing/SwingSystemTray.java | 2 ++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/dorkbox/util/tray/SystemTray.java b/src/dorkbox/util/tray/SystemTray.java index 60e0e4f..797d355 100644 --- a/src/dorkbox/util/tray/SystemTray.java +++ b/src/dorkbox/util/tray/SystemTray.java @@ -12,7 +12,7 @@ import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; -import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.slf4j.Logger; @@ -77,7 +77,7 @@ public abstract class SystemTray { } } - protected Executor callbackExecutor = Executors.newSingleThreadExecutor(new NamedThreadFactory("SysTrayExecutor", false)); + protected ExecutorService callbackExecutor = Executors.newSingleThreadExecutor(new NamedThreadFactory("SysTrayExecutor", false)); public volatile FailureCallback failureCallback; protected volatile boolean active = false; @@ -110,7 +110,10 @@ public abstract class SystemTray { } public abstract void createTray(String iconName); - public abstract void removeTray(); + + public void removeTray() { + SystemTray.this.callbackExecutor.shutdown(); + } public abstract void setStatus(String infoString, String iconName); diff --git a/src/dorkbox/util/tray/linux/AppIndicatorTray.java b/src/dorkbox/util/tray/linux/AppIndicatorTray.java index 16da019..9a9ad09 100644 --- a/src/dorkbox/util/tray/linux/AppIndicatorTray.java +++ b/src/dorkbox/util/tray/linux/AppIndicatorTray.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CountDownLatch; import com.sun.jna.Pointer; @@ -31,7 +32,7 @@ public class AppIndicatorTray extends SystemTray { private static Gobject libgobject = Gobject.INSTANCE; private static Gtk libgtk = Gtk.INSTANCE; - + private final CountDownLatch blockUntilStarted = new CountDownLatch(1); private final Map menuEntries = new HashMap(2); private volatile AppIndicator.AppIndicatorInstanceStruct appIndicator; @@ -89,6 +90,9 @@ public class AppIndicatorTray extends SystemTray { this.gtkUpdateThread = new Thread() { @Override public void run() { + // notify our main thread to continue + AppIndicatorTray.this.blockUntilStarted.countDown(); + try { libgtk.gtk_main(); } catch (Throwable t) { @@ -101,7 +105,12 @@ public class AppIndicatorTray extends SystemTray { this.gtkUpdateThread.start(); } - this.active = true; + // we CANNOT continue until the GTK thread has started! (ignored if SWT is used) + try { + this.blockUntilStarted.await(); + this.active = true; + } catch (InterruptedException e) { + } } @Override @@ -132,6 +141,8 @@ public class AppIndicatorTray extends SystemTray { } this.connectionStatusItem = null; + + super.removeTray(); } @Override diff --git a/src/dorkbox/util/tray/linux/GtkSystemTray.java b/src/dorkbox/util/tray/linux/GtkSystemTray.java index 89d0903..dbe7665 100644 --- a/src/dorkbox/util/tray/linux/GtkSystemTray.java +++ b/src/dorkbox/util/tray/linux/GtkSystemTray.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CountDownLatch; import javax.swing.JMenuItem; import javax.swing.SwingUtilities; @@ -32,6 +33,7 @@ public class GtkSystemTray extends SystemTray { private static Gobject libgobject = Gobject.INSTANCE; private static Gtk libgtk = Gtk.INSTANCE; + private final CountDownLatch blockUntilStarted = new CountDownLatch(1); private final Map menuEntries = new HashMap(2); private volatile SystemTrayMenuPopup jmenu; @@ -103,6 +105,9 @@ public class GtkSystemTray extends SystemTray { this.gtkUpdateThread = new Thread() { @Override public void run() { + // notify our main thread to continue + GtkSystemTray.this.blockUntilStarted.countDown(); + try { libgtk.gtk_main(); } catch (Throwable t) { @@ -128,7 +133,12 @@ public class GtkSystemTray extends SystemTray { logger.error("Error creating tray menu", e); } - this.active = true; + // we CANNOT continue until the GTK thread has started! (ignored if SWT is used) + try { + this.blockUntilStarted.await(); + this.active = true; + } catch (InterruptedException e) { + } } @Override @@ -157,6 +167,8 @@ public class GtkSystemTray extends SystemTray { this.jmenu = null; this.connectionStatusItem = null; + + super.removeTray(); } @Override diff --git a/src/dorkbox/util/tray/swing/SwingSystemTray.java b/src/dorkbox/util/tray/swing/SwingSystemTray.java index b32b07e..9fee9ba 100644 --- a/src/dorkbox/util/tray/swing/SwingSystemTray.java +++ b/src/dorkbox/util/tray/swing/SwingSystemTray.java @@ -69,6 +69,8 @@ public class SwingSystemTray extends dorkbox.util.tray.SystemTray { logger.error("Error updating tray menu", e); } } + + super.removeTray(); } @Override