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 "webkit/plugins/ppapi/resource_tracker.h" | 5 #include "webkit/plugins/ppapi/resource_tracker.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 | 152 |
153 instance_map_[instance].resources.erase(res); | 153 instance_map_[instance].resources.erase(res); |
154 live_resources_.erase(i); | 154 live_resources_.erase(i); |
155 } | 155 } |
156 return true; | 156 return true; |
157 } else { | 157 } else { |
158 return false; | 158 return false; |
159 } | 159 } |
160 } | 160 } |
161 | 161 |
| 162 void ResourceTracker::CleanupInstanceData(PP_Instance instance, |
| 163 bool delete_instance) { |
| 164 DLOG_IF(ERROR, !CheckIdType(instance, PP_ID_TYPE_INSTANCE)) |
| 165 << instance << " is not a PP_Instance."; |
| 166 InstanceMap::iterator found = instance_map_.find(instance); |
| 167 if (found == instance_map_.end()) { |
| 168 NOTREACHED(); |
| 169 return; |
| 170 } |
| 171 InstanceData& data = found->second; |
| 172 |
| 173 // Force release all plugin references to resources associated with the |
| 174 // deleted instance. |
| 175 ResourceSet::iterator cur_res = data.resources.begin(); |
| 176 while (cur_res != data.resources.end()) { |
| 177 ResourceMap::iterator found_resource = live_resources_.find(*cur_res); |
| 178 if (found_resource == live_resources_.end()) { |
| 179 NOTREACHED(); |
| 180 } else { |
| 181 Resource* resource = found_resource->second.first; |
| 182 |
| 183 // Must delete from the resource set first since the resource's instance |
| 184 // pointer will get zeroed out in LastPluginRefWasDeleted. |
| 185 resource->LastPluginRefWasDeleted(true); |
| 186 live_resources_.erase(*cur_res); |
| 187 } |
| 188 |
| 189 // Iterators to a set are stable so we can iterate the set while the items |
| 190 // are being deleted as long as we're careful not to delete the item we're |
| 191 // holding an iterator to. |
| 192 ResourceSet::iterator current = cur_res++; |
| 193 data.resources.erase(current); |
| 194 } |
| 195 DCHECK(data.resources.empty()); |
| 196 |
| 197 // Force delete all var references. |
| 198 VarSet::iterator cur_var = data.object_vars.begin(); |
| 199 while (cur_var != data.object_vars.end()) { |
| 200 VarSet::iterator current = cur_var++; |
| 201 |
| 202 // Tell the corresponding ObjectVar that the instance is gone. |
| 203 PP_Var object_pp_var; |
| 204 object_pp_var.type = PP_VARTYPE_OBJECT; |
| 205 object_pp_var.value.as_id = *current; |
| 206 scoped_refptr<ObjectVar> object_var(ObjectVar::FromPPVar(object_pp_var)); |
| 207 if (object_var.get()) |
| 208 object_var->InstanceDeleted(); |
| 209 |
| 210 // Clear the object from the var mapping and the live instance object list. |
| 211 live_vars_.erase(*current); |
| 212 data.object_vars.erase(*current); |
| 213 } |
| 214 DCHECK(data.object_vars.empty()); |
| 215 |
| 216 if (delete_instance) |
| 217 instance_map_.erase(found); |
| 218 } |
| 219 |
162 uint32 ResourceTracker::GetLiveObjectsForInstance( | 220 uint32 ResourceTracker::GetLiveObjectsForInstance( |
163 PP_Instance instance) const { | 221 PP_Instance instance) const { |
164 InstanceMap::const_iterator found = instance_map_.find(instance); | 222 InstanceMap::const_iterator found = instance_map_.find(instance); |
165 if (found == instance_map_.end()) | 223 if (found == instance_map_.end()) |
166 return 0; | 224 return 0; |
167 return static_cast<uint32>(found->second.resources.size() + | 225 return static_cast<uint32>(found->second.resources.size() + |
168 found->second.object_vars.size()); | 226 found->second.object_vars.size()); |
169 } | 227 } |
170 | 228 |
171 scoped_refptr<Var> ResourceTracker::GetVar(int32 var_id) const { | 229 scoped_refptr<Var> ResourceTracker::GetVar(int32 var_id) const { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 new_instance = MakeTypedId(static_cast<PP_Instance>(base::RandUint64()), | 279 new_instance = MakeTypedId(static_cast<PP_Instance>(base::RandUint64()), |
222 PP_ID_TYPE_INSTANCE); | 280 PP_ID_TYPE_INSTANCE); |
223 } while (!new_instance || | 281 } while (!new_instance || |
224 instance_map_.find(new_instance) != instance_map_.end()); | 282 instance_map_.find(new_instance) != instance_map_.end()); |
225 | 283 |
226 instance_map_[new_instance].instance = instance; | 284 instance_map_[new_instance].instance = instance; |
227 return new_instance; | 285 return new_instance; |
228 } | 286 } |
229 | 287 |
230 void ResourceTracker::InstanceDeleted(PP_Instance instance) { | 288 void ResourceTracker::InstanceDeleted(PP_Instance instance) { |
231 DLOG_IF(ERROR, !CheckIdType(instance, PP_ID_TYPE_INSTANCE)) | 289 CleanupInstanceData(instance, true); |
232 << instance << " is not a PP_Instance."; | 290 } |
233 InstanceMap::iterator found = instance_map_.find(instance); | |
234 if (found == instance_map_.end()) { | |
235 NOTREACHED(); | |
236 return; | |
237 } | |
238 InstanceData& data = found->second; | |
239 | 291 |
240 // Force release all plugin references to resources associated with the | 292 void ResourceTracker::InstanceCrashed(PP_Instance instance) { |
241 // deleted instance. | 293 CleanupInstanceData(instance, false); |
242 ResourceSet::iterator cur_res = data.resources.begin(); | |
243 while (cur_res != data.resources.end()) { | |
244 ResourceMap::iterator found_resource = live_resources_.find(*cur_res); | |
245 if (found_resource == live_resources_.end()) { | |
246 NOTREACHED(); | |
247 } else { | |
248 Resource* resource = found_resource->second.first; | |
249 | |
250 // Must delete from the resource set first since the resource's instance | |
251 // pointer will get zeroed out in LastPluginRefWasDeleted. | |
252 resource->LastPluginRefWasDeleted(true); | |
253 live_resources_.erase(*cur_res); | |
254 } | |
255 | |
256 // Iterators to a set are stable so we can iterate the set while the items | |
257 // are being deleted as long as we're careful not to delete the item we're | |
258 // holding an iterator to. | |
259 ResourceSet::iterator current = cur_res++; | |
260 data.resources.erase(current); | |
261 } | |
262 DCHECK(data.resources.empty()); | |
263 | |
264 // Force delete all var references. | |
265 VarSet::iterator cur_var = data.object_vars.begin(); | |
266 while (cur_var != data.object_vars.end()) { | |
267 VarSet::iterator current = cur_var++; | |
268 | |
269 // Tell the corresponding ObjectVar that the instance is gone. | |
270 PP_Var object_pp_var; | |
271 object_pp_var.type = PP_VARTYPE_OBJECT; | |
272 object_pp_var.value.as_id = *current; | |
273 scoped_refptr<ObjectVar> object_var(ObjectVar::FromPPVar(object_pp_var)); | |
274 if (object_var.get()) | |
275 object_var->InstanceDeleted(); | |
276 | |
277 // Clear the object from the var mapping and the live instance object list. | |
278 live_vars_.erase(*current); | |
279 data.object_vars.erase(*current); | |
280 } | |
281 DCHECK(data.object_vars.empty()); | |
282 | |
283 instance_map_.erase(found); | |
284 } | 294 } |
285 | 295 |
286 PluginInstance* ResourceTracker::GetInstance(PP_Instance instance) { | 296 PluginInstance* ResourceTracker::GetInstance(PP_Instance instance) { |
287 DLOG_IF(ERROR, !CheckIdType(instance, PP_ID_TYPE_INSTANCE)) | 297 DLOG_IF(ERROR, !CheckIdType(instance, PP_ID_TYPE_INSTANCE)) |
288 << instance << " is not a PP_Instance."; | 298 << instance << " is not a PP_Instance."; |
289 InstanceMap::iterator found = instance_map_.find(instance); | 299 InstanceMap::iterator found = instance_map_.find(instance); |
290 if (found == instance_map_.end()) | 300 if (found == instance_map_.end()) |
291 return NULL; | 301 return NULL; |
292 return found->second.instance; | 302 return found->second.instance; |
293 } | 303 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 | 349 |
340 // static | 350 // static |
341 void ResourceTracker::ClearSingletonOverride() { | 351 void ResourceTracker::ClearSingletonOverride() { |
342 DCHECK(singleton_override_); | 352 DCHECK(singleton_override_); |
343 singleton_override_ = NULL; | 353 singleton_override_ = NULL; |
344 } | 354 } |
345 | 355 |
346 } // namespace ppapi | 356 } // namespace ppapi |
347 } // namespace webkit | 357 } // namespace webkit |
348 | 358 |
OLD | NEW |