15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "fake_ppapi/fake_resource_manager.h" 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "gtest/gtest.h" 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "sdk_util/auto_lock.h" 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FakeResourceManager::FakeResourceManager() : next_handle_(1) {} 103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FakeResourceManager::~FakeResourceManager() { 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // The ref counts for all resources should be zero. 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (ResourceMap::iterator iter = resource_map_.begin(); 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) iter != resource_map_.end(); 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++iter) { 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const FakeResourceTracker* resource_tracker = iter->second; 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ(0, resource_tracker->ref_count()) << "Leaked resource " 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->classname() 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << "(" << iter->first 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << "), created at " 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->file() 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << ":" 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->line(); 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delete resource_tracker; 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)PP_Resource FakeResourceManager::Create(FakeResource* resource, 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* classname, 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* file, 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int line) { 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AUTO_LOCK(lock_); 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PP_Resource handle = next_handle_++; 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FakeResourceTracker* resource_tracker = 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new FakeResourceTracker(resource, classname, file, line); 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::pair<ResourceMap::iterator, bool> result = 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) resource_map_.insert(ResourceMap::value_type(handle, resource_tracker)); 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(result.second); 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result.first->second->AddRef(); 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return handle; 413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void FakeResourceManager::AddRef(PP_Resource handle) { 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AUTO_LOCK(lock_); 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ResourceMap::iterator iter = resource_map_.find(handle); 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT_NE(resource_map_.end(), iter) << "AddRefing unknown resource " 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << handle; 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FakeResourceTracker* resource_tracker = iter->second; 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_LT(0, resource_tracker->ref_count()) << "AddRefing freed resource " 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->classname() 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << "(" << handle 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << "), created at " 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->file() << ":" 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->line(); 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) resource_tracker->AddRef(); 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void FakeResourceManager::Release(PP_Resource handle) { 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (handle == 0) 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sdk_util::AutoLock lock(lock_); 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ResourceMap::iterator iter = resource_map_.find(handle); 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT_NE(resource_map_.end(), iter) << "Releasing unknown resource " 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << handle; 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FakeResourceTracker* resource_tracker = iter->second; 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_LT(0, resource_tracker->ref_count()) << "Releasing freed resource " 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->classname() 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << "(" << handle 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << "), created at " 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->file() << ":" 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->line(); 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) resource_tracker->Release(); 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // It's OK to access the tracker when its refcount is zero; it doesn't 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // actually destroy the object until the manager is destroyed. 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (resource_tracker->ref_count() == 0) { 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Remove the resource from this tracker. 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FakeResource* resource = resource_tracker->Pass(); 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Release the lock before we call Destroy; resources can call 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // FakeResourceManager::Release(), which will deadlock if we are already 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // holding the lock. 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) lock.Unlock(); 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) resource->Destroy(); 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delete resource; 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FakeResourceTracker* FakeResourceManager::Get(PP_Resource handle, 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool not_found_ok) { 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AUTO_LOCK(lock_); 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ResourceMap::iterator iter = resource_map_.find(handle); 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (iter == resource_map_.end()) { 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!not_found_ok) { 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Can't use FAIL() because it tries to return void. 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_TRUE(false) << "Trying to get resource " << handle 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << " that doesn't exist!"; 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return NULL; 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FakeResourceTracker* resource_tracker = iter->second; 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_LT(0, resource_tracker->ref_count()) << "Accessing freed resource " 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->classname() 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << "(" << handle 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << "), created at " 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->file() << ":" 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) << resource_tracker->line(); 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return iter->second; 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FakeResourceTracker::FakeResourceTracker(FakeResource* resource, 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* classname, 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const char* file, 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int line) 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : resource_(resource), 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) classname_(classname), 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) file_(file), 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) line_(line), 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ref_count_(0) {} 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FakeResourceTracker::~FakeResourceTracker() { delete resource_; } 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool FakeResourceTracker::CheckType(const char* other_classname) const { 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (strcmp(other_classname, classname_) != 0) { 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Repeat the expectation, just to print out a nice error message before we 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // crash. :) 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_STREQ(classname_, other_classname); 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 138