changeset 119:8ef012d564ba

PR735: Firefox 4 sometimes freezes if the applet calls showDocument()
author Deepak Bhole <dbhole@redhat.com>
date Fri, 27 May 2011 18:00:02 -0400
parents bb091ba157f2
children af4ec6073021
files ChangeLog NEWS plugin/icedteanp/IcedTeaNPPlugin.cc plugin/icedteanp/IcedTeaPluginRequestProcessor.cc plugin/icedteanp/IcedTeaPluginRequestProcessor.h plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
diffstat 6 files changed, 98 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Apr 21 11:06:03 2011 -0400
+++ b/ChangeLog	Fri May 27 18:00:02 2011 -0400
@@ -1,3 +1,20 @@
+2011-05-27  Deepak Bhole <dbhole@redhat.com>
+
+	PR735: Firefox 4 sometimes freezes if the applet calls showDocument()
+	* plugin/icedteanp/IcedTeaNPPlugin.cc (consume_message): Defer handling to
+	url load request to the queue processor.
+	* plugin/icedteanp/IcedTeaPluginRequestProcessor.cc
+	(PluginRequestProcessor::newMessageOnBus): Handle new LoadURL command.
+	(PluginRequestProcessor::loadURL): New method. Loads the specified url in
+	the given target.
+	(queue_processor): Process the LoadURL command.
+	(_loadURL): New async callback function to handle LoadURL commands.
+	* plugin/icedteanp/IcedTeaPluginRequestProcessor.h: Add _loadURL and
+	loadURL method declerations.
+	* plugin/icedteanp/java/sun/applet/PluginAppletViewer.java (showDocument):
+	Send the url load command in the standard "instance X reference Y
+	<command> <args>" format.
+
 2011-04-21  Deepak Bhole <dbhole@redhat.com>
 
 	* plugin/icedteanp/IcedTeaNPPlugin.cc (consume_message): Use
--- a/NEWS	Thu Apr 21 11:06:03 2011 -0400
+++ b/NEWS	Fri May 27 18:00:02 2011 -0400
@@ -9,6 +9,8 @@
 CVE-XXXX-YYYY: http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=XXXX-YYYY
 
 New in release 1.0.3 (2011-XX-XX):
+* Plugin
+  - PR735: Firefox 4 sometimes freezes if the applet calls showDocument()
 
 New in release 1.0.2 (2011-04-04):
 * Common Fixes and Improvements
--- a/plugin/icedteanp/IcedTeaNPPlugin.cc	Thu Apr 21 11:06:03 2011 -0400
+++ b/plugin/icedteanp/IcedTeaNPPlugin.cc	Fri May 27 18:00:02 2011 -0400
@@ -1167,26 +1167,7 @@
            data = (ITNPPluginData*) instance->pdata;
         }
 
-      if (g_str_has_prefix (parts[2], "url"))
-        {
-          // Open the URL in a new browser window.
-          gchar* decoded_url = (gchar*) calloc(strlen(parts[3]) + 1, sizeof(gchar));
-          IcedTeaPluginUtilities::decodeURL(parts[3], &decoded_url);
-
-          PLUGIN_DEBUG ("plugin_in_pipe_callback: opening URL %s\n", decoded_url);
-          PLUGIN_DEBUG ("plugin_in_pipe_callback: URL target %s\n", parts[4]);
-
-          NPError np_error =
-            (*browser_functions.geturlnotify) (data->owner, decoded_url, parts[4], NULL);
-
-
-          if (np_error != NPERR_NO_ERROR)
-            PLUGIN_ERROR ("Failed to load URL.");
-
-          g_free(decoded_url);
-          decoded_url = NULL;
-        }
-      else if (g_str_has_prefix (parts[2], "status"))
+      if (g_str_has_prefix (parts[2], "status"))
         {
 
           // clear the "instance X status" parts
--- a/plugin/icedteanp/IcedTeaPluginRequestProcessor.cc	Thu Apr 21 11:06:03 2011 -0400
+++ b/plugin/icedteanp/IcedTeaPluginRequestProcessor.cc	Fri May 27 18:00:02 2011 -0400
@@ -130,11 +130,12 @@
                    !command->find("GetSlot") ||
                    !command->find("SetSlot") ||
                    !command->find("Eval") ||
-                   !command->find("Finalize"))
+                   !command->find("Finalize") ||
+                   !command->find("LoadURL"))
         {
 
             // Update queue synchronously
-        	pthread_mutex_lock(&message_queue_mutex);
+            pthread_mutex_lock(&message_queue_mutex);
             message_queue->push_back(message_parts);
             pthread_mutex_unlock(&message_queue_mutex);
 
@@ -714,6 +715,38 @@
     plugin_to_java_bus->post(response.c_str());
 }
 
+/**
+ * Fetches the URL and loads it into the given target
+ *
+ * @param message_parts The request message.
+ */
+void
+PluginRequestProcessor::loadURL(std::vector<std::string*>* message_parts)
+{
+
+    int id = atoi(message_parts->at(1)->c_str());
+
+    AsyncCallThreadData thread_data = AsyncCallThreadData();
+    thread_data.result_ready = false;
+    thread_data.parameters = std::vector<void*>();
+    thread_data.result = std::string();
+
+    NPP instance;
+    get_instance_from_id(id, instance);
+
+    // If instance is invalid, do not proceed further
+    if (!instance)
+    	return;
+
+    thread_data.parameters.push_back(instance);
+    thread_data.parameters.push_back(message_parts->at(5)); // push url
+    thread_data.parameters.push_back(message_parts->at(6)); // push target
+
+    thread_data.result_ready = false;
+    browser_functions.pluginthreadasynccall(instance, &_loadURL, &thread_data);
+    while (!thread_data.result_ready) usleep(2000); // wait till ready
+}
+
 static void
 queue_cleanup(void* data)
 {
@@ -794,6 +827,12 @@
                 pthread_mutex_lock(&syn_write_mutex);
                 processor->finalize(message_parts);
                 pthread_mutex_unlock(&syn_write_mutex);
+            } else if (command == "LoadURL") // For instance X url <url> <target>
+            {
+                // write methods are synchronized
+                pthread_mutex_lock(&syn_write_mutex);
+                processor->loadURL(message_parts);
+                pthread_mutex_unlock(&syn_write_mutex);
             } else
             {
                 // Nothing matched
@@ -1014,3 +1053,34 @@
     PLUGIN_DEBUG("_getString returning\n");
 }
 
+void
+_loadURL(void* data) {
+
+    PLUGIN_DEBUG("_loadURL called\n");
+
+    NPP instance;
+    std::string* url;
+    std::string* target;
+
+    std::vector<void*> parameters = ((AsyncCallThreadData*) data)->parameters;
+
+    instance = (NPP) parameters.at(0);
+    url = (std::string*) parameters.at(1);
+    target = (std::string*) parameters.at(2);
+
+    PLUGIN_DEBUG("Launching %s in %s\n", url->c_str(), target->c_str());
+
+    // Each decode can expand to 4 chars at the most
+    gchar* decoded_url = (gchar*) calloc(strlen(url->c_str())*4 + 1, sizeof(gchar));
+    IcedTeaPluginUtilities::decodeURL(url->c_str(), &decoded_url);
+
+    ((AsyncCallThreadData*) data)->call_successful =
+        (*browser_functions.geturl) (instance, decoded_url, target->c_str());
+
+    ((AsyncCallThreadData*) data)->result_ready = true;
+
+    g_free(decoded_url);
+    decoded_url = NULL;
+
+    PLUGIN_DEBUG("_loadURL returning %d\n", ((AsyncCallThreadData*) data)->call_successful);
+}
--- a/plugin/icedteanp/IcedTeaPluginRequestProcessor.h	Thu Apr 21 11:06:03 2011 -0400
+++ b/plugin/icedteanp/IcedTeaPluginRequestProcessor.h	Fri May 27 18:00:02 2011 -0400
@@ -83,6 +83,7 @@
 void _call(void* data);
 void _eval(void* data);
 void _getString(void* data);
+void _loadURL(void* data);
 
 void* queue_processor(void* data);
 
@@ -138,6 +139,9 @@
 
         /* Decrements reference count for given object */
         void finalize(std::vector<std::string*>* message_parts);
+
+        /* Loads a URL into the specified target */
+        void loadURL(std::vector<std::string*>* message_parts);
 };
 
 #endif // __ICEDTEAPLUGINREQUESTPROCESSOR_H__
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Thu Apr 21 11:06:03 2011 -0400
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Fri May 27 18:00:02 2011 -0400
@@ -984,8 +984,8 @@
      */
     public void showDocument(URL url, String target) {
         try {
-            // FIXME: change to postCallRequest
-            write("url " + UrlUtil.encode(url.toString(), "UTF-8") + " " + target);
+            Long reference = getRequestIdentifier();
+            write("reference " + reference +  " LoadURL " + UrlUtil.encode(url.toString(), "UTF-8") + " " + target);
         } catch (IOException exception) {
             // Deliberately ignore IOException.  showDocument may be
             // called from threads other than the main thread after