Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "ppapi/shared_impl/callback_tracker.h" | 10 #include "ppapi/shared_impl/callback_tracker.h" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 // twice in a few cases. It would be nice not to do that and assert here | 85 // twice in a few cases. It would be nice not to do that and assert here |
| 86 // instead. | 86 // instead. |
| 87 if (instance_map_.find(instance) != instance_map_.end()) | 87 if (instance_map_.find(instance) != instance_map_.end()) |
| 88 return; | 88 return; |
| 89 instance_map_[instance] = linked_ptr<InstanceData>(new InstanceData); | 89 instance_map_[instance] = linked_ptr<InstanceData>(new InstanceData); |
| 90 } | 90 } |
| 91 | 91 |
| 92 void ResourceTracker::DidDeleteInstance(PP_Instance instance) { | 92 void ResourceTracker::DidDeleteInstance(PP_Instance instance) { |
| 93 InstanceMap::iterator found_instance = instance_map_.find(instance); | 93 InstanceMap::iterator found_instance = instance_map_.find(instance); |
| 94 | 94 |
| 95 // Due to the infrastructure of some tests, the instance is uyregistered | 95 // Due to the infrastructure of some tests, the instance is unregistered |
| 96 // twice in a few cases. It would be nice not to do that and assert here | 96 // twice in a few cases. It would be nice not to do that and assert here |
| 97 // instead. | 97 // instead. |
| 98 if (found_instance == instance_map_.end()) | 98 if (found_instance == instance_map_.end()) |
| 99 return; | 99 return; |
| 100 | 100 |
| 101 InstanceData& data = *found_instance->second; | 101 InstanceData& data = *found_instance->second; |
| 102 | 102 |
| 103 // Force release all plugin references to resources associated with the | 103 // Force release all plugin references to resources associated with the |
| 104 // deleted instance. Make a copy since as we iterate through them, each one | 104 // deleted instance. Make a copy since as we iterate through them, each one |
| 105 // will remove itself from the tracking info individually. | 105 // will remove itself from the tracking info individually. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 if (found == instance_map_.end()) | 148 if (found == instance_map_.end()) |
| 149 return 0; | 149 return 0; |
| 150 return static_cast<int>(found->second->resources.size()); | 150 return static_cast<int>(found->second->resources.size()); |
| 151 } | 151 } |
| 152 | 152 |
| 153 PP_Resource ResourceTracker::AddResource(Resource* object) { | 153 PP_Resource ResourceTracker::AddResource(Resource* object) { |
| 154 // If the plugin manages to create too many resources, don't do crazy stuff. | 154 // If the plugin manages to create too many resources, don't do crazy stuff. |
| 155 if (last_resource_value_ == kMaxPPId) | 155 if (last_resource_value_ == kMaxPPId) |
| 156 return 0; | 156 return 0; |
| 157 | 157 |
| 158 InstanceMap::iterator found = instance_map_.find(object->pp_instance()); | 158 // Allocate an ID. Note there's a rare error condition below that means we |
| 159 if (found == instance_map_.end()) { | 159 // could end up not using |new_id|, but that's harmless. |
| 160 // If you hit this, it's likely somebody forgot to call DidCreateInstance, | 160 PP_Resource new_id = MakeTypedId(++last_resource_value_, PP_ID_TYPE_RESOURCE); |
| 161 // the resource was created with an invalid PP_Instance, or the renderer | 161 |
| 162 // side tried to create a resource for a plugin that crashed/exited. This | 162 // Some objects have a 0 instance, meaning they aren't associated with any |
| 163 // could happen for OOP plugins where due to reentrancies in context of | 163 // instance, so they won't be in |instance_map_|. This is (as of this writing) |
| 164 // outgoing sync calls the renderer can send events after a plugin has | 164 // only true of the PPB_MessageLoop resource for the main thread. |
|
bbudge
2012/08/29 22:26:58
Close ')' or just delete '('
Could the key '0' be
dmichael (off chromium)
2012/08/30 15:59:10
I think it's closed?
"(as of this writing)"
| |
| 165 // exited. | 165 if (object->pp_instance()) { |
| 166 DLOG(INFO) << "Failed to find plugin instance in instance map"; | 166 InstanceMap::iterator found = instance_map_.find(object->pp_instance()); |
| 167 return 0; | 167 if (found == instance_map_.end()) { |
| 168 // If you hit this, it's likely somebody forgot to call DidCreateInstance, | |
| 169 // the resource was created with an invalid PP_Instance, or the renderer | |
| 170 // side tried to create a resource for a plugin that crashed/exited. This | |
| 171 // could happen for OOP plugins where due to reentrancies in context of | |
| 172 // outgoing sync calls the renderer can send events after a plugin has | |
| 173 // exited. | |
| 174 DLOG(INFO) << "Failed to find plugin instance in instance map"; | |
| 175 return 0; | |
| 176 } | |
| 177 found->second->resources.insert(new_id); | |
| 168 } | 178 } |
| 169 | 179 |
| 170 PP_Resource new_id = MakeTypedId(++last_resource_value_, PP_ID_TYPE_RESOURCE); | |
| 171 found->second->resources.insert(new_id); | |
| 172 | |
| 173 live_resources_[new_id] = ResourceAndRefCount(object, 0); | 180 live_resources_[new_id] = ResourceAndRefCount(object, 0); |
| 174 return new_id; | 181 return new_id; |
| 175 } | 182 } |
| 176 | 183 |
| 177 void ResourceTracker::RemoveResource(Resource* object) { | 184 void ResourceTracker::RemoveResource(Resource* object) { |
| 178 PP_Resource pp_resource = object->pp_resource(); | 185 PP_Resource pp_resource = object->pp_resource(); |
| 179 InstanceMap::iterator found = instance_map_.find(object->pp_instance()); | 186 InstanceMap::iterator found = instance_map_.find(object->pp_instance()); |
| 180 if (found != instance_map_.end()) | 187 if (found != instance_map_.end()) |
| 181 found->second->resources.erase(pp_resource); | 188 found->second->resources.erase(pp_resource); |
| 182 live_resources_.erase(pp_resource); | 189 live_resources_.erase(pp_resource); |
| 183 } | 190 } |
| 184 | 191 |
| 185 void ResourceTracker::LastPluginRefWasDeleted(Resource* object) { | 192 void ResourceTracker::LastPluginRefWasDeleted(Resource* object) { |
| 186 // Bug http://crbug.com/134611 indicates that sometimes the resource tracker | 193 // Bug http://crbug.com/134611 indicates that sometimes the resource tracker |
| 187 // is null here. This should never be the case since if we have a resource in | 194 // is null here. This should never be the case since if we have a resource in |
| 188 // the tracker, it should always have a valid instance associated with it. | 195 // the tracker, it should always have a valid instance associated with it |
| 196 // (except for the resource for the main thread's message loop, which has | |
| 197 // instance set to 0). | |
| 189 // As a result, we do some CHECKs here to see what types of problems the | 198 // As a result, we do some CHECKs here to see what types of problems the |
| 190 // instance might have before dispatching. | 199 // instance might have before dispatching. |
| 191 // | 200 // |
| 192 // TODO(brettw) remove these checks when this bug is no longer relevant. | 201 // TODO(brettw) remove these checks when this bug is no longer relevant. |
| 193 CHECK(object->pp_instance()); | 202 // Note, we do an imperfect check here; this might be a loop that's not the |
| 203 // main one. | |
| 204 const bool is_message_loop = (object->AsPPB_MessageLoop_API() != NULL); | |
| 205 CHECK(object->pp_instance() || is_message_loop); | |
| 194 CallbackTracker* callback_tracker = | 206 CallbackTracker* callback_tracker = |
| 195 PpapiGlobals::Get()->GetCallbackTrackerForInstance(object->pp_instance()); | 207 PpapiGlobals::Get()->GetCallbackTrackerForInstance(object->pp_instance()); |
| 196 CHECK(callback_tracker); | 208 CHECK(callback_tracker || is_message_loop); |
| 197 callback_tracker->PostAbortForResource(object->pp_resource()); | 209 if (callback_tracker) |
| 210 callback_tracker->PostAbortForResource(object->pp_resource()); | |
| 198 object->LastPluginRefWasDeleted(); | 211 object->LastPluginRefWasDeleted(); |
| 199 } | 212 } |
| 200 | 213 |
| 201 } // namespace ppapi | 214 } // namespace ppapi |
| OLD | NEW |