diff options
author | cdn@chromium.org <cdn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-20 22:33:52 +0000 |
---|---|---|
committer | cdn@chromium.org <cdn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-20 22:33:52 +0000 |
commit | 55ef04e135edaa9abfbf3647634b11ed57dc49e9 (patch) | |
tree | b3f773e9905a3ed82e9ee121073171af50c16870 /webkit/plugins | |
parent | 3eb5728c989094f6f6b24a392fd49255e5b1e5dc (diff) | |
download | chromium_src-55ef04e135edaa9abfbf3647634b11ed57dc49e9.zip chromium_src-55ef04e135edaa9abfbf3647634b11ed57dc49e9.tar.gz chromium_src-55ef04e135edaa9abfbf3647634b11ed57dc49e9.tar.bz2 |
Maintain a map of all resources in the resource tracker and clear instance back pointers when needed,
BUG=85808
Review URL: http://codereview.chromium.org/7196001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@89746 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/plugins')
-rw-r--r-- | webkit/plugins/ppapi/ppb_url_loader_impl.cc | 10 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_url_loader_impl.h | 2 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_widget_impl.cc | 2 | ||||
-rw-r--r-- | webkit/plugins/ppapi/resource.cc | 7 | ||||
-rw-r--r-- | webkit/plugins/ppapi/resource.h | 16 | ||||
-rw-r--r-- | webkit/plugins/ppapi/resource_tracker.cc | 49 | ||||
-rw-r--r-- | webkit/plugins/ppapi/resource_tracker.h | 7 |
7 files changed, 62 insertions, 31 deletions
diff --git a/webkit/plugins/ppapi/ppb_url_loader_impl.cc b/webkit/plugins/ppapi/ppb_url_loader_impl.cc index 3b57d12..103ea5c 100644 --- a/webkit/plugins/ppapi/ppb_url_loader_impl.cc +++ b/webkit/plugins/ppapi/ppb_url_loader_impl.cc @@ -86,13 +86,9 @@ PPB_URLLoader_API* PPB_URLLoader_Impl::AsPPB_URLLoader_API() { return this; } -void PPB_URLLoader_Impl::LastPluginRefWasDeleted(bool instance_destroyed) { - Resource::LastPluginRefWasDeleted(instance_destroyed); - if (instance_destroyed) { - // Free the WebKit request when the instance has been destroyed to avoid - // using bandwidth just in case this object lives longer than the instance. - loader_.reset(); - } +void PPB_URLLoader_Impl::ClearInstance() { + Resource::ClearInstance(); + loader_.reset(); } int32_t PPB_URLLoader_Impl::Open(PP_Resource request_id, diff --git a/webkit/plugins/ppapi/ppb_url_loader_impl.h b/webkit/plugins/ppapi/ppb_url_loader_impl.h index f931406..e2794e0 100644 --- a/webkit/plugins/ppapi/ppb_url_loader_impl.h +++ b/webkit/plugins/ppapi/ppb_url_loader_impl.h @@ -42,7 +42,7 @@ class PPB_URLLoader_Impl : public Resource, virtual ::ppapi::thunk::PPB_URLLoader_API* AsPPB_URLLoader_API() OVERRIDE; // Resource overrides. - virtual void LastPluginRefWasDeleted(bool instance_destroyed) OVERRIDE; + virtual void ClearInstance() OVERRIDE; // PPB_URLLoader_API implementation. virtual int32_t Open(PP_Resource request_id, diff --git a/webkit/plugins/ppapi/ppb_widget_impl.cc b/webkit/plugins/ppapi/ppb_widget_impl.cc index 300955d..c079a74 100644 --- a/webkit/plugins/ppapi/ppb_widget_impl.cc +++ b/webkit/plugins/ppapi/ppb_widget_impl.cc @@ -95,6 +95,8 @@ void PPB_Widget_Impl::SetLocation(const PP_Rect* location) { } void PPB_Widget_Impl::Invalidate(const PP_Rect* dirty) { + if (!instance()) + return; const PPP_Widget_Dev* widget = static_cast<const PPP_Widget_Dev*>( instance()->module()->GetPluginInterface(PPP_WIDGET_DEV_INTERFACE)); if (!widget) diff --git a/webkit/plugins/ppapi/resource.cc b/webkit/plugins/ppapi/resource.cc index 9619861..bb9ad4d 100644 --- a/webkit/plugins/ppapi/resource.cc +++ b/webkit/plugins/ppapi/resource.cc @@ -15,9 +15,11 @@ namespace ppapi { Resource::Resource(PluginInstance* instance) : resource_id_(0), instance_(instance) { + ResourceTracker::Get()->ResourceCreated(this, instance_); } Resource::~Resource() { + ResourceTracker::Get()->ResourceDestroyed(this); } PP_Resource Resource::GetReference() { @@ -33,14 +35,11 @@ PP_Resource Resource::GetReferenceNoAddRef() const { return resource_id_; } -void Resource::LastPluginRefWasDeleted(bool instance_destroyed) { +void Resource::LastPluginRefWasDeleted() { DCHECK(resource_id_ != 0); instance()->module()->GetCallbackTracker()->PostAbortForResource( resource_id_); resource_id_ = 0; - - if (instance_destroyed) - instance_ = NULL; } #define DEFINE_TYPE_GETTER(RESOURCE) \ diff --git a/webkit/plugins/ppapi/resource.h b/webkit/plugins/ppapi/resource.h index 0f86fa1..0d3b99e 100644 --- a/webkit/plugins/ppapi/resource.h +++ b/webkit/plugins/ppapi/resource.h @@ -67,6 +67,12 @@ class Resource : public base::RefCountedThreadSafe<Resource>, // PPAPI implementation is keeping a reference for some reason. PluginInstance* instance() const { return instance_; } + // Clears the instance pointer when the associated PluginInstance will be + // destroyed. + // + // If you override this, be sure to call the base class' implementation. + virtual void ClearInstance() { instance_ = NULL; } + // Cast the resource into a specified type. This will return NULL if the // resource does not match the specified type. Specializations of this // template call into As* functions. @@ -110,16 +116,8 @@ class Resource : public base::RefCountedThreadSafe<Resource>, // stay alive if there are other references held by the PPAPI implementation // (possibly for callbacks and things). // - // When the plugin instance is deleted, all resources associated with that - // plugin will have their plugin references force-deleted and this function - // will be called with instance_destroyed as true. If the plugin normally - // Release()s a reference before the instance is destroyed, - // instance_destroyed will be false. It's possible in some rare cases for the - // plugin to get a new reference to the object in this latter case, if it's - // stored internal to the PPAPI implementation and returned by some function. - // // If you override this, be sure to call the base class' implementation. - virtual void LastPluginRefWasDeleted(bool instance_destroyed); + virtual void LastPluginRefWasDeleted(); private: // Type-specific getters for individual resource types. These will return diff --git a/webkit/plugins/ppapi/resource_tracker.cc b/webkit/plugins/ppapi/resource_tracker.cc index 1787012..ed65a2a 100644 --- a/webkit/plugins/ppapi/resource_tracker.cc +++ b/webkit/plugins/ppapi/resource_tracker.cc @@ -66,7 +66,8 @@ struct ResourceTracker::InstanceData { PluginInstance* instance; // Resources and object vars associated with the instance. - ResourceSet resources; + ResourceSet ref_resources; + std::set<Resource*> assoc_resources; VarSet object_vars; // Lazily allocated function proxies for the different interfaces. @@ -107,6 +108,27 @@ ResourceTracker* ResourceTracker::Get() { return global_tracker_; } +void ResourceTracker::ResourceCreated(Resource* resource, + PluginInstance* instance) { + if (!instance) + return; + PP_Instance pp_instance = instance->pp_instance(); + DCHECK(pp_instance); + DCHECK(instance_map_.find(pp_instance) != instance_map_.end()); + instance_map_[pp_instance]->assoc_resources.insert(resource); +} + +void ResourceTracker::ResourceDestroyed(Resource* resource) { + if (!resource->instance()) + return; + + PP_Instance pp_instance = resource->instance()->pp_instance(); + DCHECK(pp_instance); + DCHECK(instance_map_.find(pp_instance) != instance_map_.end()); + + instance_map_[pp_instance]->assoc_resources.erase(resource); +} + PP_Resource ResourceTracker::AddResource(Resource* resource) { // If the plugin manages to create 1 billion resources, don't do crazy stuff. if (last_resource_id_ == @@ -120,7 +142,7 @@ PP_Resource ResourceTracker::AddResource(Resource* resource) { // Track associated with the instance. PP_Instance pp_instance = resource->instance()->pp_instance(); DCHECK(instance_map_.find(pp_instance) != instance_map_.end()); - instance_map_[pp_instance]->resources.insert(new_id); + instance_map_[pp_instance]->ref_resources.insert(new_id); return new_id; } @@ -169,9 +191,9 @@ bool ResourceTracker::UnrefResource(PP_Resource res) { // LastPluginRefWasDeleted will clear the instance pointer, so save it // first. PP_Instance instance = to_release->instance()->pp_instance(); - to_release->LastPluginRefWasDeleted(false); + to_release->LastPluginRefWasDeleted(); - instance_map_[instance]->resources.erase(res); + instance_map_[instance]->ref_resources.erase(res); live_resources_.erase(i); } return true; @@ -193,8 +215,8 @@ void ResourceTracker::CleanupInstanceData(PP_Instance instance, // Force release all plugin references to resources associated with the // deleted instance. - ResourceSet::iterator cur_res = data.resources.begin(); - while (cur_res != data.resources.end()) { + ResourceSet::iterator cur_res = data.ref_resources.begin(); + while (cur_res != data.ref_resources.end()) { ResourceMap::iterator found_resource = live_resources_.find(*cur_res); if (found_resource == live_resources_.end()) { NOTREACHED(); @@ -203,7 +225,7 @@ void ResourceTracker::CleanupInstanceData(PP_Instance instance, // Must delete from the resource set first since the resource's instance // pointer will get zeroed out in LastPluginRefWasDeleted. - resource->LastPluginRefWasDeleted(true); + resource->LastPluginRefWasDeleted(); live_resources_.erase(*cur_res); } @@ -211,9 +233,9 @@ void ResourceTracker::CleanupInstanceData(PP_Instance instance, // are being deleted as long as we're careful not to delete the item we're // holding an iterator to. ResourceSet::iterator current = cur_res++; - data.resources.erase(current); + data.ref_resources.erase(current); } - DCHECK(data.resources.empty()); + DCHECK(data.ref_resources.empty()); // Force delete all var references. VarSet::iterator cur_var = data.object_vars.begin(); @@ -234,6 +256,13 @@ void ResourceTracker::CleanupInstanceData(PP_Instance instance, } DCHECK(data.object_vars.empty()); + // Clear any resources that still reference this instance. + for (std::set<Resource*>::iterator res = data.assoc_resources.begin(); + res != data.assoc_resources.end(); + ++res) + (*res)->ClearInstance(); + data.assoc_resources.clear(); + if (delete_instance) instance_map_.erase(found); } @@ -243,7 +272,7 @@ uint32 ResourceTracker::GetLiveObjectsForInstance( InstanceMap::const_iterator found = instance_map_.find(instance); if (found == instance_map_.end()) return 0; - return static_cast<uint32>(found->second->resources.size() + + return static_cast<uint32>(found->second->ref_resources.size() + found->second->object_vars.size()); } diff --git a/webkit/plugins/ppapi/resource_tracker.h b/webkit/plugins/ppapi/resource_tracker.h index d5618e6..b728895 100644 --- a/webkit/plugins/ppapi/resource_tracker.h +++ b/webkit/plugins/ppapi/resource_tracker.h @@ -120,6 +120,13 @@ class ResourceTracker : public ::ppapi::TrackerBase { ResourceTracker(); ~ResourceTracker(); + // Called when a new resource is created and associates it with its + // PluginInstance. + void ResourceCreated(Resource* resource, PluginInstance* instance); + + // Removes a resource from the resource map. + void ResourceDestroyed(Resource* resource); + // Adds the given resource to the tracker and assigns it a resource ID and // refcount of 1. The assigned resource ID will be returned. Used only by the // Resource class. |