Re: [gui-dev] Startup deadlock problems
Jens-Uwe Mager <[email protected]> Fri, 23 Jul 2004 23:34:15 +0200
| Newsgroups | gmane.network.gnutella.limewire.gui.devel |
|---|---|
| Message-ID | <[email protected]> |
On Fri, Jul 23, 2004 at 15:06 -0400, Sam Berlin wrote: > Yeah, the startup is pretty fragile. We'll gladly accept a patch that > puts the construction in the Swing thread & still manages to update the > splash screen. :) OK, it does not need to be that an intrusive patch to get it working properly. Sprinkleing a few SwingUtilities.invokeAndWait() into the source does it. I did change the following three places that are prone to the deadlock problem: * SplashWindow: updating the status text modifies a realized window. * StatusLine: same problem. * GUIMediator.setAppVisible: making the main frame visible while other threads do updates to the GUI already (via SwingUtilities.invokeLater) produces a dead lock main thread against the Swing event dispatcher thread. Especially the third one is the one that affected my additional main tab, it implements a scrollable console window via BeanShell that may already do prints to a console window. This is in particular visible if logging via log4j is redirected to the console window. The attached patch does indeed make the deadlock go away, but it appears to have one side effect under Windows that I do not understand. The code that does iconify LimeWire to the system tray does not appear to work with my patch, it simply iconifies to the task bar. The code appears to be highly magical, do you have any clues what might be causing the breakage? -- Jens-Uwe Mager <pgp-mailto:F476EBC2> _______________________________________________ gui-dev mailing list [email protected] http://www.limewire.org/mailman/listinfo/gui-dev
st.patch
(text/plain, 3.9 KB)
Index: com/limegroup/gnutella/gui/SplashWindow.java
===================================================================
RCS file: /cvs/gui/com/limegroup/gnutella/gui/SplashWindow.java,v
retrieving revision 1.26
diff -u -r1.26 SplashWindow.java
--- com/limegroup/gnutella/gui/SplashWindow.java 10 Jun 2004 19:11:11 -0000 1.26
+++ com/limegroup/gnutella/gui/SplashWindow.java 23 Jul 2004 21:08:50 -0000
@@ -1,6 +1,7 @@
package com.limegroup.gnutella.gui;
import com.limegroup.gnutella.settings.ThemeFileHandler;
+import com.limegroup.gnutella.ErrorService;
import javax.swing.*;
import java.awt.*;
@@ -59,8 +60,16 @@
*
* @param text the text to display
*/
- static void setStatusText(String text) {
- GLASS_PANE.setText(text);
+ static void setStatusText(final String text) {
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ GLASS_PANE.setText(text);
+ }
+ });
+ } catch (Exception ex) {
+ ErrorService.error(ex);
+ }
}
}
Index: com/limegroup/gnutella/gui/StatusLine.java
===================================================================
RCS file: /cvs/gui/com/limegroup/gnutella/gui/StatusLine.java,v
retrieving revision 1.89
diff -u -r1.89 StatusLine.java
--- com/limegroup/gnutella/gui/StatusLine.java 21 May 2004 17:09:51 -0000 1.89
+++ com/limegroup/gnutella/gui/StatusLine.java 23 Jul 2004 21:08:51 -0000
@@ -4,6 +4,7 @@
import java.awt.*;
import javax.swing.*;
import com.limegroup.gnutella.util.CommonUtils;
+import com.limegroup.gnutella.ErrorService;
import com.limegroup.gnutella.gui.mp3.*;
import com.limegroup.gnutella.settings.*;
@@ -160,10 +161,18 @@
* Updates the status text.
*/
void setStatusText(final String text) {
- STATUS_LABEL.setText(text);
- STATUS_LABEL.invalidate();
- STATUS_LABEL.revalidate();
- STATUS_LABEL.repaint();
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ STATUS_LABEL.setText(text);
+ STATUS_LABEL.invalidate();
+ STATUS_LABEL.revalidate();
+ STATUS_LABEL.repaint();
+ }
+ });
+ } catch (Exception ex) {
+ ErrorService.error(ex);
+ }
}
/**
Index: com/limegroup/gnutella/gui/GUIMediator.java
===================================================================
RCS file: /cvs/gui/com/limegroup/gnutella/gui/GUIMediator.java,v
retrieving revision 1.136
diff -u -r1.136 GUIMediator.java
--- com/limegroup/gnutella/gui/GUIMediator.java 15 Jul 2004 15:47:50 -0000 1.136
+++ com/limegroup/gnutella/gui/GUIMediator.java 23 Jul 2004 21:08:53 -0000
@@ -2,6 +2,7 @@
import com.limegroup.gnutella.RouterService;
import com.limegroup.gnutella.bugs.BugManager;
+import com.limegroup.gnutella.ErrorService;
import com.limegroup.gnutella.gui.library.LibraryMediator;
import com.limegroup.gnutella.gui.notify.*;
import com.limegroup.gnutella.gui.options.OptionsMediator;
@@ -311,9 +318,17 @@
* @param visible specifies whether or not the application should be
* made visible or not
*/
- public static final void setAppVisible(boolean visible) {
- FRAME.setVisible(visible);
- SearchMediator.requestSearchFocus();
+ public static final void setAppVisible(final boolean visible) {
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ FRAME.setVisible(visible);
+ SearchMediator.requestSearchFocus();
+ }
+ });
+ } catch (Exception ex) {
+ ErrorService.error(ex);
+ }
// If the app has already been made visible, don't display extra
// dialogs. We could display the pro dialog here, but it causes