15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/resource_tracker.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/callback_tracker.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/id_assignment.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/resource.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ResourceTracker::ResourceTracker(ThreadMode thread_mode) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : last_resource_value_(0), 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (thread_mode == SINGLE_THREADED) 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) thread_checker_.reset(new base::ThreadChecker); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ResourceTracker::~ResourceTracker() { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceTracker::CheckThreadingPreconditions() const { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!thread_checker_ || thread_checker_->CalledOnValidThread()); 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef NDEBUG 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyLock::AssertAcquired(); 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Resource* ResourceTracker::GetResource(PP_Resource res) const { 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceMap::const_iterator i = live_resources_.find(res); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == live_resources_.end()) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i->second.first; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceTracker::AddRefResource(PP_Resource res) { 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE)) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << res << " is not a PP_Resource."; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceMap::iterator i = live_resources_.find(res); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == live_resources_.end()) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent overflow of refcount. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->second.second == 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::numeric_limits<ResourceAndRefCount::second_type>::max()) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When we go from 0 to 1 plugin ref count, keep an additional "real" ref 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on its behalf. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->second.second == 0) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second.first->AddRef(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second.second++; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceTracker::ReleaseResource(PP_Resource res) { 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE)) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << res << " is not a PP_Resource."; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceMap::iterator i = live_resources_.find(res); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == live_resources_.end()) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent underflow of refcount. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->second.second == 0) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second.second--; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->second.second == 0) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LastPluginRefWasDeleted(i->second.first); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When we go from 1 to 0 plugin ref count, free the additional "real" ref 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on its behalf. THIS WILL MOST LIKELY RELEASE THE OBJECT AND REMOVE IT 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FROM OUR LIST. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second.first->Release(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceTracker::ReleaseResourceSoon(PP_Resource res) { 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostNonNestableTask( 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunWhileLocked(base::Bind(&ResourceTracker::ReleaseResource, 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) res))); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceTracker::DidCreateInstance(PP_Instance instance) { 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Due to the infrastructure of some tests, the instance is registered 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // twice in a few cases. It would be nice not to do that and assert here 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instead. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (instance_map_.find(instance) != instance_map_.end()) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_map_[instance] = linked_ptr<InstanceData>(new InstanceData); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceTracker::DidDeleteInstance(PP_Instance instance) { 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceMap::iterator found_instance = instance_map_.find(instance); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Due to the infrastructure of some tests, the instance is unregistered 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // twice in a few cases. It would be nice not to do that and assert here 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instead. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found_instance == instance_map_.end()) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceData& data = *found_instance->second; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force release all plugin references to resources associated with the 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deleted instance. Make a copy since as we iterate through them, each one 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will remove itself from the tracking info individually. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceSet to_delete = data.resources; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceSet::iterator cur = to_delete.begin(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cur != to_delete.end()) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that it's remotely possible for the object to already be deleted 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the live resources. One case is if a resource object is holding 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the last ref to another. When we release the first one, it will release 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the second one. So the second one will be gone when we eventually get 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to it. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceMap::iterator found_resource = live_resources_.find(*cur); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found_resource != live_resources_.end()) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resource* resource = found_resource->second.first; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found_resource->second.second > 0) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LastPluginRefWasDeleted(resource); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_resource->second.second = 0; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will most likely delete the resource object and remove it 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the live_resources_ list. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource->Release(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur++; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In general the above pass will delete all the resources and there won't 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be any left in the map. However, if parts of the implementation are still 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // holding on to internal refs, we need to tell them that the instance is 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // gone. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_delete = data.resources; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = to_delete.begin(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cur != to_delete.end()) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceMap::iterator found_resource = live_resources_.find(*cur); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found_resource != live_resources_.end()) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_resource->second.first->NotifyInstanceWasDeleted(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur++; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_map_.erase(instance); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ResourceTracker::GetLiveObjectsForInstance(PP_Instance instance) const { 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceMap::const_iterator found = instance_map_.find(instance); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found == instance_map_.end()) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(found->second->resources.size()); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource ResourceTracker::AddResource(Resource* object) { 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the plugin manages to create too many resources, don't do crazy stuff. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_resource_value_ == kMaxPPId) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate an ID. Note there's a rare error condition below that means we 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // could end up not using |new_id|, but that's harmless. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource new_id = MakeTypedId(++last_resource_value_, PP_ID_TYPE_RESOURCE); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some objects have a 0 instance, meaning they aren't associated with any 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instance, so they won't be in |instance_map_|. This is (as of this writing) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only true of the PPB_MessageLoop resource for the main thread. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (object->pp_instance()) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceMap::iterator found = instance_map_.find(object->pp_instance()); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found == instance_map_.end()) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If you hit this, it's likely somebody forgot to call DidCreateInstance, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the resource was created with an invalid PP_Instance, or the renderer 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // side tried to create a resource for a plugin that crashed/exited. This 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // could happen for OOP plugins where due to reentrancies in context of 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // outgoing sync calls the renderer can send events after a plugin has 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exited. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(INFO) << "Failed to find plugin instance in instance map"; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found->second->resources.insert(new_id); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) live_resources_[new_id] = ResourceAndRefCount(object, 0); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new_id; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceTracker::RemoveResource(Resource* object) { 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource pp_resource = object->pp_resource(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstanceMap::iterator found = instance_map_.find(object->pp_instance()); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found != instance_map_.end()) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found->second->resources.erase(pp_resource); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) live_resources_.erase(pp_resource); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ResourceTracker::LastPluginRefWasDeleted(Resource* object) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bug http://crbug.com/134611 indicates that sometimes the resource tracker 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is null here. This should never be the case since if we have a resource in 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the tracker, it should always have a valid instance associated with it 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (except for the resource for the main thread's message loop, which has 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instance set to 0). 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // As a result, we do some CHECKs here to see what types of problems the 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instance might have before dispatching. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(brettw) remove these checks when this bug is no longer relevant. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note, we do an imperfect check here; this might be a loop that's not the 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // main one. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool is_message_loop = (object->AsPPB_MessageLoop_API() != NULL); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(object->pp_instance() || is_message_loop); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallbackTracker* callback_tracker = 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PpapiGlobals::Get()->GetCallbackTrackerForInstance(object->pp_instance()); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(callback_tracker || is_message_loop); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (callback_tracker) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_tracker->PostAbortForResource(object->pp_resource()); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object->NotifyLastPluginRefWasDeleted(); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 233