[gnome-shell] browser-plugin: Do not create a new object every time NPPVpluginScriptableNPObject is requested
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] browser-plugin: Do not create a new object every time NPPVpluginScriptableNPObject is requested
- Date: Tue, 17 Nov 2015 19:17:43 +0000 (UTC)
commit d95d78ac15778c497e30e07c1d78b0827f72f5bb
Author: Carlos Garcia Campos <cgarcia igalia com>
Date: Tue Nov 17 14:41:03 2015 +0100
browser-plugin: Do not create a new object every time NPPVpluginScriptableNPObject is requested
Merge PluginData and PluginObject structs into a single one and create
the scriptable object associated to the plugin instance in NPP_New. Then,
when NPPVpluginScriptableNPObject is requested we just return the
scriptable object associated to the given instance. This caused the
crashes in NPN_InvokeDefault with WebKit, since we had multiple
scriptable objects for the same instance, but only one of those objects
had the onchange listener installed. Firefox seems to cache the
scriptable object for the instance and therefore NPPVpluginScriptableNPObject
is requested only once.
https://bugzilla.gnome.org/show_bug.cgi?id=737932
browser-plugin/browser-plugin.c | 306 +++++++++++++++++++--------------------
1 files changed, 150 insertions(+), 156 deletions(-)
---
diff --git a/browser-plugin/browser-plugin.c b/browser-plugin/browser-plugin.c
index dbeac33..4555a96 100644
--- a/browser-plugin/browser-plugin.c
+++ b/browser-plugin/browser-plugin.c
@@ -43,10 +43,6 @@
#define EXTENSION_DISABLE_VERSION_CHECK_KEY "disable-extension-version-validation"
-typedef struct {
- GDBusProxy *proxy;
-} PluginData;
-
static NPNetscapeFuncs funcs;
static inline gchar *
@@ -145,125 +141,6 @@ check_origin_and_protocol (NPP instance)
return ret;
}
-/* =============== public entry points =================== */
-
-NPError
-NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
-{
- /* global initialization routine, called once when plugin
- is loaded */
-
- g_debug ("plugin loaded");
-
- memcpy (&funcs, pfuncs, sizeof (funcs));
-
- plugin->size = sizeof(NPPluginFuncs);
- plugin->newp = NPP_New;
- plugin->destroy = NPP_Destroy;
- plugin->getvalue = NPP_GetValue;
- plugin->setwindow = NPP_SetWindow;
- plugin->event = NPP_HandleEvent;
-
- return NPERR_NO_ERROR;
-}
-
-NPError
-NP_Shutdown(void)
-{
- return NPERR_NO_ERROR;
-}
-
-const char*
-NP_GetMIMEDescription(void)
-{
- return PLUGIN_MIME_STRING;
-}
-
-NPError
-NP_GetValue(void *instance,
- NPPVariable variable,
- void *value)
-{
- switch (variable) {
- case NPPVpluginNameString:
- *(char**)value = PLUGIN_NAME;
- break;
- case NPPVpluginDescriptionString:
- *(char**)value = PLUGIN_DESCRIPTION;
- break;
- default:
- ;
- }
-
- return NPERR_NO_ERROR;
-}
-
-NPError
-NPP_New(NPMIMEType mimetype,
- NPP instance,
- uint16_t mode,
- int16_t argc,
- char **argn,
- char **argv,
- NPSavedData *saved)
-{
- /* instance initialization function */
- PluginData *data;
- GError *error = NULL;
-
- g_debug ("plugin created");
-
- if (!check_origin_and_protocol (instance))
- return NPERR_GENERIC_ERROR;
-
- data = g_slice_new (PluginData);
- instance->pdata = data;
-
- /* set windowless mode */
- funcs.setvalue(instance, NPPVpluginWindowBool, NULL);
-
- data->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL, /* interface info */
- "org.gnome.Shell",
- "/org/gnome/Shell",
- "org.gnome.Shell.Extensions",
- NULL, /* GCancellable */
- &error);
- if (!data->proxy)
- {
- /* ignore error if the shell is not running, otherwise warn */
- if (error->domain != G_DBUS_ERROR ||
- error->code != G_DBUS_ERROR_NAME_HAS_NO_OWNER)
- {
- g_warning ("Failed to set up Shell proxy: %s", error->message);
- }
- g_clear_error (&error);
- return NPERR_GENERIC_ERROR;
- }
-
- g_debug ("plugin created successfully");
-
- return NPERR_NO_ERROR;
-}
-
-NPError
-NPP_Destroy(NPP instance,
- NPSavedData **saved)
-{
- /* instance finalization function */
-
- PluginData *data = instance->pdata;
-
- g_debug ("plugin destroyed");
-
- g_object_unref (data->proxy);
-
- g_slice_free (PluginData, data);
-
- return NPERR_NO_ERROR;
-}
-
/* =================== scripting interface =================== */
typedef struct {
@@ -334,45 +211,18 @@ static NPObject *
plugin_object_allocate (NPP instance,
NPClass *klass)
{
- PluginData *data = instance->pdata;
- PluginObject *obj = g_slice_new0 (PluginObject);
+ PluginObject *obj = (PluginObject *) funcs.memalloc (sizeof (PluginObject));
+ memset (obj, 0, sizeof (PluginObject));
obj->instance = instance;
- obj->proxy = g_object_ref (data->proxy);
- obj->settings = g_settings_new (SHELL_SCHEMA);
- obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
- G_CALLBACK (on_shell_signal), obj);
- obj->watch_name_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
- "org.gnome.Shell",
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- on_shell_appeared,
- NULL,
- obj,
- NULL);
-
- g_debug ("plugin object created");
-
- return (NPObject*)obj;
+ return (NPObject*) obj;
}
static void
plugin_object_deallocate (NPObject *npobj)
{
- PluginObject *obj = (PluginObject*)npobj;
-
- g_signal_handler_disconnect (obj->proxy, obj->signal_id);
- g_object_unref (obj->proxy);
-
- if (obj->listener)
- funcs.releaseobject (obj->listener);
-
- if (obj->watch_name_id)
- g_bus_unwatch_name (obj->watch_name_id);
-
- g_debug ("plugin object destroyed");
-
- g_slice_free (PluginObject, obj);
+ funcs.memfree (npobj);
}
static inline gboolean
@@ -1023,6 +873,149 @@ init_methods_and_properties (void)
onextension_changed_id = funcs.getstringidentifier ("onchange");
}
+/* =============== public entry points =================== */
+
+NPError
+NP_Initialize(NPNetscapeFuncs *pfuncs, NPPluginFuncs *plugin)
+{
+ /* global initialization routine, called once when plugin
+ is loaded */
+
+ g_debug ("plugin loaded");
+
+ memcpy (&funcs, pfuncs, sizeof (funcs));
+
+ plugin->size = sizeof(NPPluginFuncs);
+ plugin->newp = NPP_New;
+ plugin->destroy = NPP_Destroy;
+ plugin->getvalue = NPP_GetValue;
+ plugin->setwindow = NPP_SetWindow;
+ plugin->event = NPP_HandleEvent;
+
+ return NPERR_NO_ERROR;
+}
+
+NPError
+NP_Shutdown(void)
+{
+ return NPERR_NO_ERROR;
+}
+
+const char*
+NP_GetMIMEDescription(void)
+{
+ return PLUGIN_MIME_STRING;
+}
+
+NPError
+NP_GetValue(void *instance,
+ NPPVariable variable,
+ void *value)
+{
+ switch (variable) {
+ case NPPVpluginNameString:
+ *(char**)value = PLUGIN_NAME;
+ break;
+ case NPPVpluginDescriptionString:
+ *(char**)value = PLUGIN_DESCRIPTION;
+ break;
+ default:
+ ;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError
+NPP_New(NPMIMEType mimetype,
+ NPP instance,
+ uint16_t mode,
+ int16_t argc,
+ char **argn,
+ char **argv,
+ NPSavedData *saved)
+{
+ /* instance initialization function */
+ PluginObject *obj;
+ GError *error = NULL;
+
+ g_debug ("plugin created");
+
+ if (!check_origin_and_protocol (instance))
+ return NPERR_GENERIC_ERROR;
+
+ /* set windowless mode */
+ funcs.setvalue(instance, NPPVpluginWindowBool, NULL);
+
+ g_debug ("creating scriptable object");
+ init_methods_and_properties ();
+ obj = (PluginObject *) funcs.createobject (instance, &plugin_class);
+ instance->pdata = obj;
+
+ obj->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL, /* interface info */
+ "org.gnome.Shell",
+ "/org/gnome/Shell",
+ "org.gnome.Shell.Extensions",
+ NULL, /* GCancellable */
+ &error);
+ if (!obj->proxy)
+ {
+ /* ignore error if the shell is not running, otherwise warn */
+ if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER))
+ {
+ g_warning ("Failed to set up Shell proxy: %s", error->message);
+ }
+ g_clear_error (&error);
+ return NPERR_GENERIC_ERROR;
+ }
+
+ obj->settings = g_settings_new (SHELL_SCHEMA);
+ obj->signal_id = g_signal_connect (obj->proxy, "g-signal",
+ G_CALLBACK (on_shell_signal), obj);
+ obj->watch_name_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
+ "org.gnome.Shell",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ on_shell_appeared,
+ NULL,
+ obj,
+ NULL);
+
+ g_debug ("plugin created successfully");
+
+ return NPERR_NO_ERROR;
+}
+
+NPError
+NPP_Destroy(NPP instance,
+ NPSavedData **saved)
+{
+ /* instance finalization function */
+ PluginObject *obj = (PluginObject *) instance->pdata;
+
+ if (!obj)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ g_debug ("plugin destroyed");
+
+ g_signal_handler_disconnect (obj->proxy, obj->signal_id);
+ g_object_unref (obj->proxy);
+
+ if (obj->listener)
+ funcs.releaseobject (obj->listener);
+
+ if (obj->restart_listener)
+ funcs.releaseobject (obj->restart_listener);
+
+ if (obj->watch_name_id)
+ g_bus_unwatch_name (obj->watch_name_id);
+
+ funcs.releaseobject((NPObject *)obj);
+
+ return NPERR_NO_ERROR;
+}
+
NPError
NPP_GetValue(NPP instance,
NPPVariable variable,
@@ -1033,9 +1026,10 @@ NPP_GetValue(NPP instance,
switch (variable) {
case NPPVpluginScriptableNPObject:
g_debug ("creating scriptable object");
- init_methods_and_properties ();
+ if (!instance->pdata)
+ return NPERR_INVALID_INSTANCE_ERROR;
- *(NPObject**)value = funcs.createobject (instance, &plugin_class);
+ *(NPObject**)value = instance->pdata;
break;
default:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]