summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/plugin_var_tracker.h
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-18 19:41:30 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-18 19:41:30 +0000
commitedb5b05700f53fb7b1827727777cc15b50370ccb (patch)
tree4cc0fc0bf581503e6fd273a037a63353ca41bf9c /ppapi/proxy/plugin_var_tracker.h
parentdc20acdfb4026b23709beec34a187dfde58af437 (diff)
downloadchromium_src-edb5b05700f53fb7b1827727777cc15b50370ccb.zip
chromium_src-edb5b05700f53fb7b1827727777cc15b50370ccb.tar.gz
chromium_src-edb5b05700f53fb7b1827727777cc15b50370ccb.tar.bz2
Actually free plugin implement vars when running out of process when the
plugin holds a reference beyond the lifetime of the instance. Review URL: https://chromiumcodereview.appspot.com/10542150 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142787 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy/plugin_var_tracker.h')
-rw-r--r--ppapi/proxy/plugin_var_tracker.h77
1 files changed, 77 insertions, 0 deletions
diff --git a/ppapi/proxy/plugin_var_tracker.h b/ppapi/proxy/plugin_var_tracker.h
index cafb3ab..3e287be 100644
--- a/ppapi/proxy/plugin_var_tracker.h
+++ b/ppapi/proxy/plugin_var_tracker.h
@@ -17,6 +17,7 @@
#include "ppapi/shared_impl/var_tracker.h"
template<typename T> struct DefaultSingletonTraits;
+struct PPP_Class_Deprecated;
namespace ppapi {
@@ -56,6 +57,28 @@ class PPAPI_PROXY_EXPORT PluginVarTracker : public VarTracker {
void ReleaseHostObject(PluginDispatcher* dispatcher,
const PP_Var& host_object);
+ // VarTracker public overrides.
+ void DidDeleteInstance(PP_Instance instance) OVERRIDE;
+
+ // Notification that a plugin-implemented object (PPP_Class) was created by
+ // the plugin or deallocated by WebKit over IPC.
+ void PluginImplementedObjectCreated(PP_Instance instance,
+ const PP_Var& created_var,
+ const PPP_Class_Deprecated* ppp_class,
+ void* ppp_class_data);
+ void PluginImplementedObjectDestroyed(void* ppp_class_data);
+
+ // Returns true if there is an object implemented by the plugin with the
+ // given user_data that has not been deallocated yet. Call this when
+ // receiving a scripting call to the plugin to validate that the object
+ // receiving the call is still alive (see user_data_to_plugin_ below).
+ bool IsPluginImplementedObjectAlive(void* user_data);
+
+ // Validates that the given class/user_data pair corresponds to a currently
+ // living plugin object.
+ bool ValidatePluginObjectCall(const PPP_Class_Deprecated* ppp_class,
+ void* user_data);
+
private:
// VarTracker protected overrides.
virtual int32 AddVarInternal(Var* var, AddVarRefMode mode) OVERRIDE;
@@ -84,6 +107,32 @@ class PPAPI_PROXY_EXPORT PluginVarTracker : public VarTracker {
int32 host_object_id;
};
+ struct PluginImplementedVar {
+ const PPP_Class_Deprecated* ppp_class;
+
+ // The instance that created this Var. This will be 0 if the instance has
+ // been destroyed but the object is still alive.
+ PP_Instance instance;
+
+ // Represents the plugin var ID for the var corresponding to this object.
+ // If the plugin does not have a ref to the object but it's still alive
+ // (the DOM could be holding a ref keeping it alive) this will be 0.
+ //
+ // There is an obscure corner case. If the plugin returns an object to the
+ // renderer and releases all of its refs, the object will still be alive
+ // but there will be no plugin refs. It's possible for the plugin to get
+ // this same object again through the DOM, and we'll lose the correlation
+ // between plugin implemented object and car. This means we won't know when
+ // the plugin releases its last refs and may call Deallocate when the
+ // plugin is still holding a ref.
+ //
+ // However, for the plugin to be depending on holding a ref to an object
+ // that it implements that it previously released but got again through
+ // indirect means would be extremely rare, and we only allow var scripting
+ // in limited cases anyway.
+ int32 plugin_object_id;
+ };
+
// Returns the existing var ID for the given object var, creating and
// assigning an ID to it if necessary. This does not affect the reference
// count, so in the creation case the refcount will be 0. It's assumed in
@@ -106,6 +155,34 @@ class PPAPI_PROXY_EXPORT PluginVarTracker : public VarTracker {
typedef std::map<HostVar, int32> HostVarToPluginVarMap;
HostVarToPluginVarMap host_var_to_plugin_var_;
+ // Maps "user data" for plugin implemented objects (PPP_Class) that are
+ // alive to various tracking info.
+ //
+ // This is tricky because there may not actually be any vars in the plugin
+ // associated with a plugin-implemented object, so they won't all have
+ // entries in our HostVarToPluginVarMap or the base class VarTracker's map.
+ //
+ // All objects that the plugin has created using CreateObject that have not
+ // yet been Deallocate()-ed by WebKit will be in this map. When the instance
+ // that created the object goes away, we know to call Deallocate on all
+ // remaining objects for that instance so that the data backing the object
+ // that the plugin owns is not leaked. We may not receive normal Deallocate
+ // calls from WebKit because the object could be leaked (attached to the DOM
+ // and outliving the plugin instance) or WebKit could send the deallocate
+ // after the out-of-process routing for that instance was torn down.
+ //
+ // There is an additional complexity. In WebKit, objects created by the
+ // plugin aren't actually bound to the plugin instance (for example, you
+ // could attach it to the DOM or send it to another plugin instance). It's
+ // possible that we could force deallocate an object when an instance id
+ // destroyed, but then another instance could get to that object somehow
+ // (like by reading it out of the DOM). We will then have deallocated the
+ // object and can't complete the call. We do not care about this case, and
+ // the calls will just fail.
+ typedef std::map<void*, PluginImplementedVar>
+ UserDataToPluginImplementedVarMap;
+ UserDataToPluginImplementedVarMap user_data_to_plugin_;
+
DISALLOW_COPY_AND_ASSIGN(PluginVarTracker);
};