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 |