Fix resource destruction in proxy
This ensures that the resource on the plugin side is destroyed before we send
the message to the host, so that it has a chance to do proper cleanup.
Also, fix Surface3D destruction that could cause a write-after-free.
BUG=none
TEST=go to youtube with out-of-process pepper flash. click on fullscreen.
observe no hang, no crash
Review URL: http://codereview.chromium.org/6771042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80188 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/ppapi/proxy/plugin_resource_tracker.cc b/ppapi/proxy/plugin_resource_tracker.cc
index 0c4bdfb..2e9e32a 100644
--- a/ppapi/proxy/plugin_resource_tracker.cc
+++ b/ppapi/proxy/plugin_resource_tracker.cc
@@ -120,24 +120,25 @@
return;
found->second.ref_count--;
if (found->second.ref_count == 0) {
- PluginResource* plugin_resource = found->second.resource.get();
- if (notify_browser_on_release)
- SendReleaseResourceToHost(resource, plugin_resource);
- host_resource_map_.erase(plugin_resource->host_resource());
+ // Keep a reference while removing in case the destructor ends up
+ // re-entering. That way, when the destructor is called, it's out of the
+ // maps.
+ linked_ptr<PluginResource> plugin_resource = found->second.resource;
+ PluginDispatcher* dispatcher =
+ PluginDispatcher::GetForInstance(plugin_resource->instance());
+ HostResource host_resource = plugin_resource->host_resource();
+ host_resource_map_.erase(host_resource);
resource_map_.erase(found);
- }
-}
+ plugin_resource.reset();
-void PluginResourceTracker::SendReleaseResourceToHost(
- PP_Resource resource_id,
- PluginResource* resource) {
- PluginDispatcher* dispatcher =
- PluginDispatcher::GetForInstance(resource->instance());
- if (dispatcher) {
- dispatcher->Send(new PpapiHostMsg_PPBCore_ReleaseResource(
- INTERFACE_ID_PPB_CORE, resource->host_resource()));
- } else {
- NOTREACHED();
+ if (notify_browser_on_release) {
+ if (dispatcher) {
+ dispatcher->Send(new PpapiHostMsg_PPBCore_ReleaseResource(
+ INTERFACE_ID_PPB_CORE, host_resource));
+ } else {
+ NOTREACHED();
+ }
+ }
}
}