| Index: ppapi/proxy/plugin_var_tracker.h
|
| ===================================================================
|
| --- ppapi/proxy/plugin_var_tracker.h (revision 141525)
|
| +++ ppapi/proxy/plugin_var_tracker.h (working copy)
|
| @@ -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 @@
|
| 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 @@
|
| 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 @@
|
| 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);
|
| };
|
|
|
|
|