changeset 694:142217481a51

Fix a dead-lock bug that can cause Firefox to hang.
author Adam Domurad <adomurad@redhat.com>
date Thu, 25 Apr 2013 10:53:44 -0400
parents b0bef68756a6
children 8515c529e29c
files ChangeLog netx/net/sourceforge/jnlp/NetxPanel.java plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
diffstat 3 files changed, 24 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Apr 25 10:28:08 2013 -0400
+++ b/ChangeLog	Thu Apr 25 10:53:44 2013 -0400
@@ -1,3 +1,17 @@
+2013-04-25  Adam Domurad  <adomurad@redhat.com>
+
+	Fix a dead-lock that can cause (namely) Firefox to hang.
+	* netx/net/sourceforge/jnlp/NetxPanel.java
+	(appletAlive): Remove flag.
+	(isAlive): Remove getter.
+	(initialized): New, explicit initialization flag.
+	(isInitialized): New, getter.
+	(runLoader): Set initialization flag when done (whether errored or not).
+	* plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
+	(waitForAppletInit): Wait on initialization flag from NetxPanel.
+	(handleMessage): Remove redundant waiting for init. Respond properly to
+	GetJavaObject in case of error/time-out.
+
 2013-04-25  Adam Domurad  <adomurad@redhat.com>
 
 	* tests/netx/unit/net/sourceforge/jnlp/AsyncCallTest.java: Unit tests for
--- a/netx/net/sourceforge/jnlp/NetxPanel.java	Thu Apr 25 10:28:08 2013 -0400
+++ b/netx/net/sourceforge/jnlp/NetxPanel.java	Thu Apr 25 10:53:44 2013 -0400
@@ -39,7 +39,7 @@
 
 /**
  * This panel calls into netx to run an applet, and pipes the display
- * into a panel from gcjwebplugin.
+ * into a panel from the icedtea-web browser plugin.
  *
  * @author      Francis Kung <fkung@redhat.com>
  */
@@ -48,7 +48,7 @@
     private PluginBridge bridge = null;
     private AppletInstance appInst = null;
     private SplashController splashController;
-    private boolean appletAlive;
+    private volatile boolean initialized;
 
     // We use this so that we can create exactly one thread group
     // for all panels with the same uKey.
@@ -70,6 +70,7 @@
         super(documentURL, params.getUnderlyingHashtable());
 
         this.parameters = params;
+        this.initialized = false;
 
         String uniqueKey = params.getUniqueKey(getCodeBase());
         synchronized(TGMapMutex) {
@@ -78,7 +79,6 @@
                 uKeyToTG.put(uniqueKey, tg);
             }
         }
-        this.appletAlive = true;
     }
 
     @Override
@@ -124,7 +124,6 @@
                 validate();
             }
         } catch (Exception e) {
-            this.appletAlive = false;
             status = APPLET_ERROR;
             e.printStackTrace();
             replaceSplash(SplashUtils.getErrorSplashScreen(getWidth(), getHeight(), e));
@@ -133,6 +132,7 @@
             // so that the applet's event listeners are signaled.
             // Once PluginAppletViewer.AppletEventListener is signaled PluginAppletViewer can properly stop waiting
             // in PluginAppletViewer.waitForAppletInit
+            this.initialized = true;
             dispatchAppletEvent(APPLET_LOADING_COMPLETED, null);
         }
     }
@@ -170,8 +170,8 @@
         return appInst.getClassLoader();
     }
 
-    public boolean isAlive() {
-        return handler != null && handler.isAlive() && this.appletAlive;
+    public boolean isInitialized() {
+        return initialized;
     }
 
     public ThreadGroup getThreadGroup() {
@@ -191,9 +191,6 @@
         }
     }
 
-    
-   
-
     public void setAppletViewerFrame(SplashController framePanel) {
         splashController=framePanel;
     }
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Thu Apr 25 10:28:08 2013 -0400
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Thu Apr 25 10:53:44 2013 -0400
@@ -652,8 +652,7 @@
 
         panelLock.lock();
         try {
-            while (panel.getApplet() == null &&
-                    panel.isAlive() &&
+            while (!panel.isInitialized() && 
                     maxTimeToSleep > 0) {
                 PluginDebug.debug("Waiting for applet panel ", panel, " to initialize...");
                 maxTimeToSleep -= waitTillTimeout(panelLock, panelLive, maxTimeToSleep);
@@ -731,37 +730,16 @@
             // object should belong to?
             Object o;
 
-            // First, wait for panel to instantiate
-            // Next, wait for panel to come alive
-            long maxTimeToSleep = APPLET_TIMEOUT;
-            panelLock.lock();
-            try {
-                while (panel == null || !panel.isAlive()) {
-                    maxTimeToSleep -= waitTillTimeout(panelLock, panelLive,
-                                                      maxTimeToSleep);
-
-                    /* we already waited till timeout, give up here directly,
-                     *  instead of waiting 180s again in below waitForAppletInit()
-                     */
-                    if(maxTimeToSleep < 0) {
-                        streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError: " + "Initialization timed out");
-                        return;
-                    }
-                }
-            }
-            finally {
-                panelLock.unlock();
-            }
-
             // Wait for the panel to initialize
             // (happens in a separate thread)
             waitForAppletInit(panel);
 
-            PluginDebug.debug(panel, " -- ", panel.getApplet(), " -- ", panel.isAlive());
+            PluginDebug.debug(panel, " -- ", panel.getApplet(), " -- initialized: ", panel.isInitialized());
 
             // Still null?
             if (panel.getApplet() == null) {
-                streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError: " + "Initialization timed out");
+                streamhandler.write("instance " + identifier + " reference " + -1 + " fatalError: " + "Initialization failed");
+                streamhandler.write("context 0 reference " + reference + " Error");
                 return;
             }