| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ppapi/shared_impl/resource_tracker.h" | 5 #include "ppapi/shared_impl/resource_tracker.h" |
| 6 | 6 |
| 7 #include "ppapi/shared_impl/id_assignment.h" | 7 #include "ppapi/shared_impl/id_assignment.h" |
| 8 #include "ppapi/shared_impl/resource.h" | 8 #include "ppapi/shared_impl/resource.h" |
| 9 | 9 |
| 10 namespace ppapi { | 10 namespace ppapi { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 ResourceMap::iterator i = live_resources_.find(res); | 49 ResourceMap::iterator i = live_resources_.find(res); |
| 50 if (i == live_resources_.end()) | 50 if (i == live_resources_.end()) |
| 51 return; | 51 return; |
| 52 | 52 |
| 53 // Prevent underflow of refcount. | 53 // Prevent underflow of refcount. |
| 54 if (i->second.second == 0) | 54 if (i->second.second == 0) |
| 55 return; | 55 return; |
| 56 | 56 |
| 57 i->second.second--; | 57 i->second.second--; |
| 58 if (i->second.second == 0) { | 58 if (i->second.second == 0) { |
| 59 i->second.first->LastPluginRefWasDeleted(); | 59 LastPluginRefWasDeleted(i->second.first); |
| 60 | 60 |
| 61 // When we go from 1 to 0 plugin ref count, free the additional "real" ref | 61 // When we go from 1 to 0 plugin ref count, free the additional "real" ref |
| 62 // on its behalf. THIS WILL MOST LIKELY RELEASE THE OBJECT AND REMOVE IT | 62 // on its behalf. THIS WILL MOST LIKELY RELEASE THE OBJECT AND REMOVE IT |
| 63 // FROM OUR LIST. | 63 // FROM OUR LIST. |
| 64 i->second.first->Release(); | 64 i->second.first->Release(); |
| 65 } | 65 } |
| 66 } | 66 } |
| 67 | 67 |
| 68 void ResourceTracker::DidCreateInstance(PP_Instance instance) { | 68 void ResourceTracker::DidCreateInstance(PP_Instance instance) { |
| 69 // Due to the infrastructure of some tests, the instance is registered | 69 // Due to the infrastructure of some tests, the instance is registered |
| (...skipping 23 matching lines...) Expand all Loading... |
| 93 while (cur != to_delete.end()) { | 93 while (cur != to_delete.end()) { |
| 94 // Note that it's remotely possible for the object to already be deleted | 94 // Note that it's remotely possible for the object to already be deleted |
| 95 // from the live resources. One case is if a resource object is holding | 95 // from the live resources. One case is if a resource object is holding |
| 96 // the last ref to another. When we release the first one, it will release | 96 // the last ref to another. When we release the first one, it will release |
| 97 // the second one. So the second one will be gone when we eventually get | 97 // the second one. So the second one will be gone when we eventually get |
| 98 // to it. | 98 // to it. |
| 99 ResourceMap::iterator found_resource = live_resources_.find(*cur); | 99 ResourceMap::iterator found_resource = live_resources_.find(*cur); |
| 100 if (found_resource != live_resources_.end()) { | 100 if (found_resource != live_resources_.end()) { |
| 101 Resource* resource = found_resource->second.first; | 101 Resource* resource = found_resource->second.first; |
| 102 if (found_resource->second.second > 0) { | 102 if (found_resource->second.second > 0) { |
| 103 resource->LastPluginRefWasDeleted(); | 103 LastPluginRefWasDeleted(resource); |
| 104 found_resource->second.second = 0; | 104 found_resource->second.second = 0; |
| 105 | 105 |
| 106 // This will most likely delete the resource object and remove it | 106 // This will most likely delete the resource object and remove it |
| 107 // from the live_resources_ list. | 107 // from the live_resources_ list. |
| 108 resource->Release(); | 108 resource->Release(); |
| 109 } | 109 } |
| 110 } | 110 } |
| 111 | 111 |
| 112 cur++; | 112 cur++; |
| 113 } | 113 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 135 return static_cast<int>(found->second->resources.size()); | 135 return static_cast<int>(found->second->resources.size()); |
| 136 } | 136 } |
| 137 | 137 |
| 138 PP_Resource ResourceTracker::AddResource(Resource* object) { | 138 PP_Resource ResourceTracker::AddResource(Resource* object) { |
| 139 // If the plugin manages to create too many resources, don't do crazy stuff. | 139 // If the plugin manages to create too many resources, don't do crazy stuff. |
| 140 if (last_resource_value_ == kMaxPPId) | 140 if (last_resource_value_ == kMaxPPId) |
| 141 return 0; | 141 return 0; |
| 142 | 142 |
| 143 // If you hit this somebody forgot to call DidCreateInstance or the resource | 143 // If you hit this somebody forgot to call DidCreateInstance or the resource |
| 144 // was created with an invalid PP_Instance. | 144 // was created with an invalid PP_Instance. |
| 145 DCHECK(instance_map_.find(object->pp_instance()) != instance_map_.end()); | 145 // |
| 146 // This is specifically a check even in release mode. When creating resources |
| 147 // it can be easy to forget to validate the instance parameter. If somebody |
| 148 // does forget, we don't want to introduce a vulnerability with invalid |
| 149 // pointers floating around, so we die ASAP. |
| 150 InstanceMap::iterator found = instance_map_.find(object->pp_instance()); |
| 151 CHECK(found != instance_map_.end()); |
| 146 | 152 |
| 147 PP_Resource new_id = MakeTypedId(++last_resource_value_, PP_ID_TYPE_RESOURCE); | 153 PP_Resource new_id = MakeTypedId(++last_resource_value_, PP_ID_TYPE_RESOURCE); |
| 148 instance_map_[object->pp_instance()]->resources.insert(new_id); | 154 found->second->resources.insert(new_id); |
| 149 | 155 |
| 150 live_resources_[new_id] = ResourceAndRefCount(object, 0); | 156 live_resources_[new_id] = ResourceAndRefCount(object, 0); |
| 151 return new_id; | 157 return new_id; |
| 152 } | 158 } |
| 153 | 159 |
| 154 void ResourceTracker::RemoveResource(Resource* object) { | 160 void ResourceTracker::RemoveResource(Resource* object) { |
| 155 PP_Resource pp_resource = object->pp_resource(); | 161 PP_Resource pp_resource = object->pp_resource(); |
| 156 if (object->pp_instance()) | 162 if (object->pp_instance()) |
| 157 instance_map_[object->pp_instance()]->resources.erase(pp_resource); | 163 instance_map_[object->pp_instance()]->resources.erase(pp_resource); |
| 158 live_resources_.erase(pp_resource); | 164 live_resources_.erase(pp_resource); |
| 159 } | 165 } |
| 160 | 166 |
| 167 void ResourceTracker::LastPluginRefWasDeleted(Resource* object) { |
| 168 object->LastPluginRefWasDeleted(); |
| 169 } |
| 170 |
| 161 } // namespace ppapi | 171 } // namespace ppapi |
| OLD | NEW |