diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-18 19:41:30 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-18 19:41:30 +0000 |
commit | edb5b05700f53fb7b1827727777cc15b50370ccb (patch) | |
tree | 4cc0fc0bf581503e6fd273a037a63353ca41bf9c /ppapi/proxy/plugin_var_tracker.h | |
parent | dc20acdfb4026b23709beec34a187dfde58af437 (diff) | |
download | chromium_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.h | 77 |
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); }; |