Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Unified Diff: ppapi/proxy/plugin_var_tracker.cc

Issue 10542150: Actually free plugin implement vars when running out of process when the (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/proxy/plugin_var_tracker.h ('k') | ppapi/proxy/plugin_var_tracker_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/proxy/plugin_var_tracker.cc
===================================================================
--- ppapi/proxy/plugin_var_tracker.cc (revision 141525)
+++ ppapi/proxy/plugin_var_tracker.cc (working copy)
@@ -6,6 +6,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
+#include "ppapi/c/dev/ppp_class_deprecated.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/proxy/plugin_array_buffer_var.h"
#include "ppapi/proxy/plugin_dispatcher.h"
@@ -151,10 +152,79 @@
ReleaseVar(found->second);
}
+void PluginVarTracker::DidDeleteInstance(PP_Instance instance) {
+ // See the comment above user_data_to_plugin_ in the header file. We assume
+ // there aren't that many objects so a brute-force search is reasonable.
+ UserDataToPluginImplementedVarMap::iterator i =
+ user_data_to_plugin_.begin();
+ while (i != user_data_to_plugin_.end()) {
+ if (i->second.instance == instance) {
+ if (!i->second.plugin_object_id) {
+ // This object is for the freed instance and the plugin is not holding
+ // any references to it. Deallocate immediately.
+ UserDataToPluginImplementedVarMap::iterator to_remove = i;
+ ++i;
+ to_remove->second.ppp_class->Deallocate(to_remove->first);
+ user_data_to_plugin_.erase(to_remove);
+ } else {
+ // The plugin is holding refs to this object. We don't want to call
+ // Deallocate since the plugin may be depending on those refs to keep
+ // its data alive. To avoid crashes in this case, just clear out the
+ // instance to mark it and continue. When the plugin refs go to 0,
+ // we'll notice there is no instance and call Deallocate.
+ i->second.instance = 0;
+ ++i;
+ }
+ } else {
+ ++i;
+ }
+ }
+}
+
ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) {
return new PluginArrayBufferVar(size_in_bytes);
}
+void PluginVarTracker::PluginImplementedObjectCreated(
+ PP_Instance instance,
+ const PP_Var& created_var,
+ const PPP_Class_Deprecated* ppp_class,
+ void* ppp_class_data) {
+ PluginImplementedVar p;
+ p.ppp_class = ppp_class;
+ p.instance = instance;
+ p.plugin_object_id = created_var.value.as_id;
+ user_data_to_plugin_[ppp_class_data] = p;
+
+ // Link the user data to the object.
+ ProxyObjectVar* object = GetVar(created_var)->AsProxyObjectVar();
+ object->set_user_data(ppp_class_data);
+}
+
+void PluginVarTracker::PluginImplementedObjectDestroyed(void* user_data) {
+ UserDataToPluginImplementedVarMap::iterator found =
+ user_data_to_plugin_.find(user_data);
+ if (found == user_data_to_plugin_.end()) {
+ NOTREACHED();
+ return;
+ }
+ user_data_to_plugin_.erase(found);
+}
+
+bool PluginVarTracker::IsPluginImplementedObjectAlive(void* user_data) {
+ return user_data_to_plugin_.find(user_data) != user_data_to_plugin_.end();
+}
+
+bool PluginVarTracker::ValidatePluginObjectCall(
+ const PPP_Class_Deprecated* ppp_class,
+ void* user_data) {
+ UserDataToPluginImplementedVarMap::iterator found =
+ user_data_to_plugin_.find(user_data);
+ if (found == user_data_to_plugin_.end())
+ return false;
+ return found->second.ppp_class == ppp_class;
+}
+
int32 PluginVarTracker::AddVarInternal(Var* var, AddVarRefMode mode) {
// Normal adding.
int32 new_id = VarTracker::AddVarInternal(var, mode);
@@ -200,6 +270,26 @@
DCHECK(iter->second.ref_count == 0);
SendReleaseObjectMsg(*object);
+ UserDataToPluginImplementedVarMap::iterator found =
+ user_data_to_plugin_.find(object->user_data());
+ if (found != user_data_to_plugin_.end()) {
+ // This object is implemented in the plugin.
+ if (found->second.instance == 0) {
+ // Instance is destroyed. This means that we'll never get a Deallocate
+ // call from the renderer and we should do so now.
+ found->second.ppp_class->Deallocate(found->first);
+ user_data_to_plugin_.erase(found);
+ } else {
+ // The plugin is releasing its last reference to an object it implements.
+ // Clear the tracking data that links our "plugin implemented object" to
+ // the var. If the instance is destroyed and there is no ID, we know that
+ // we should just call Deallocate on the object data.
+ //
+ // See the plugin_object_id declaration for more info.
+ found->second.plugin_object_id = 0;
+ }
+ }
+
// This will optionally delete the info from live_vars_.
VarTracker::ObjectGettingZeroRef(iter);
}
« no previous file with comments | « ppapi/proxy/plugin_var_tracker.h ('k') | ppapi/proxy/plugin_var_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698