host_var_tracker.cc revision 58e6fbe4ee35d65e14b626c557d37565bf8ad179
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/renderer/pepper/host_var_tracker.h" 6 7#include "base/logging.h" 8#include "content/renderer/pepper/host_array_buffer_var.h" 9#include "content/renderer/pepper/npobject_var.h" 10#include "content/renderer/pepper/pepper_plugin_instance_impl.h" 11#include "ppapi/c/pp_var.h" 12 13using ppapi::ArrayBufferVar; 14using ppapi::NPObjectVar; 15 16namespace content { 17 18HostVarTracker::HostVarTracker() 19 : VarTracker(SINGLE_THREADED), 20 last_shared_memory_map_id_(0) { 21} 22 23HostVarTracker::~HostVarTracker() { 24} 25 26ArrayBufferVar* HostVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { 27 return new HostArrayBufferVar(size_in_bytes); 28} 29 30ArrayBufferVar* HostVarTracker::CreateShmArrayBuffer( 31 uint32 size_in_bytes, 32 base::SharedMemoryHandle handle) { 33 return new HostArrayBufferVar(size_in_bytes, handle); 34} 35 36void HostVarTracker::AddNPObjectVar(NPObjectVar* object_var) { 37 CheckThreadingPreconditions(); 38 39 InstanceMap::iterator found_instance = instance_map_.find( 40 object_var->pp_instance()); 41 if (found_instance == instance_map_.end()) { 42 // Lazily create the instance map. 43 DCHECK(object_var->pp_instance() != 0); 44 found_instance = instance_map_.insert(std::make_pair( 45 object_var->pp_instance(), 46 linked_ptr<NPObjectToNPObjectVarMap>(new NPObjectToNPObjectVarMap))). 47 first; 48 } 49 NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get(); 50 51 DCHECK(np_object_map->find(object_var->np_object()) == 52 np_object_map->end()) << "NPObjectVar already in map"; 53 np_object_map->insert(std::make_pair(object_var->np_object(), object_var)); 54} 55 56void HostVarTracker::RemoveNPObjectVar(NPObjectVar* object_var) { 57 CheckThreadingPreconditions(); 58 59 InstanceMap::iterator found_instance = instance_map_.find( 60 object_var->pp_instance()); 61 if (found_instance == instance_map_.end()) { 62 NOTREACHED() << "NPObjectVar has invalid instance."; 63 return; 64 } 65 NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get(); 66 67 NPObjectToNPObjectVarMap::iterator found_object = 68 np_object_map->find(object_var->np_object()); 69 if (found_object == np_object_map->end()) { 70 NOTREACHED() << "NPObjectVar not registered."; 71 return; 72 } 73 if (found_object->second != object_var) { 74 NOTREACHED() << "NPObjectVar doesn't match."; 75 return; 76 } 77 np_object_map->erase(found_object); 78} 79 80NPObjectVar* HostVarTracker::NPObjectVarForNPObject(PP_Instance instance, 81 NPObject* np_object) { 82 CheckThreadingPreconditions(); 83 84 InstanceMap::iterator found_instance = instance_map_.find(instance); 85 if (found_instance == instance_map_.end()) 86 return NULL; // No such instance. 87 NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get(); 88 89 NPObjectToNPObjectVarMap::iterator found_object = 90 np_object_map->find(np_object); 91 if (found_object == np_object_map->end()) 92 return NULL; // No such object. 93 return found_object->second; 94} 95 96int HostVarTracker::GetLiveNPObjectVarsForInstance(PP_Instance instance) const { 97 CheckThreadingPreconditions(); 98 99 InstanceMap::const_iterator found = instance_map_.find(instance); 100 if (found == instance_map_.end()) 101 return 0; 102 return static_cast<int>(found->second->size()); 103} 104 105void HostVarTracker::DidDeleteInstance(PP_Instance instance) { 106 CheckThreadingPreconditions(); 107 108 InstanceMap::iterator found_instance = instance_map_.find(instance); 109 if (found_instance == instance_map_.end()) 110 return; // Nothing to do. 111 NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get(); 112 113 // Force delete all var references. ForceReleaseNPObject() will cause 114 // this object, and potentially others it references, to be removed from 115 // |np_object_map|. 116 while (!np_object_map->empty()) { 117 ForceReleaseNPObject(np_object_map->begin()->second); 118 } 119 120 // Remove the record for this instance since it should be empty. 121 DCHECK(np_object_map->empty()); 122 instance_map_.erase(found_instance); 123} 124 125void HostVarTracker::ForceReleaseNPObject(::ppapi::NPObjectVar* object_var) { 126 object_var->InstanceDeleted(); 127 VarMap::iterator iter = live_vars_.find(object_var->GetExistingVarID()); 128 if (iter == live_vars_.end()) { 129 NOTREACHED(); 130 return; 131 } 132 iter->second.ref_count = 0; 133 DCHECK(iter->second.track_with_no_reference_count == 0); 134 DeleteObjectInfoIfNecessary(iter); 135} 136 137int HostVarTracker::TrackSharedMemoryHandle(PP_Instance instance, 138 base::SharedMemoryHandle handle, 139 uint32 size_in_bytes) { 140 SharedMemoryMapEntry entry; 141 entry.instance = instance; 142 entry.handle = handle; 143 entry.size_in_bytes = size_in_bytes; 144 145 // Find a free id for our map. 146 while (shared_memory_map_.find(last_shared_memory_map_id_) != 147 shared_memory_map_.end()) { 148 ++last_shared_memory_map_id_; 149 } 150 shared_memory_map_[last_shared_memory_map_id_] = entry; 151 return last_shared_memory_map_id_; 152} 153 154bool HostVarTracker::StopTrackingSharedMemoryHandle( 155 int id, 156 PP_Instance instance, 157 base::SharedMemoryHandle* handle, 158 uint32* size_in_bytes) { 159 SharedMemoryMap::iterator it = shared_memory_map_.find(id); 160 if (it == shared_memory_map_.end()) 161 return false; 162 if (it->second.instance != instance) 163 return false; 164 165 *handle = it->second.handle; 166 *size_in_bytes = it->second.size_in_bytes; 167 shared_memory_map_.erase(it); 168 return true; 169} 170 171} // namespace content 172