| 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/proxy/plugin_var_tracker.h" | 5 #include "ppapi/proxy/plugin_var_tracker.h" |
| 6 | 6 |
| 7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
| 8 #include "base/memory/singleton.h" | 8 #include "base/memory/singleton.h" |
| 9 #include "ppapi/c/dev/ppp_class_deprecated.h" | 9 #include "ppapi/c/dev/ppp_class_deprecated.h" |
| 10 #include "ppapi/c/ppb_var.h" | 10 #include "ppapi/c/ppb_var.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 if (found == host_var_to_plugin_var_.end()) { | 146 if (found == host_var_to_plugin_var_.end()) { |
| 147 NOTREACHED(); | 147 NOTREACHED(); |
| 148 return; | 148 return; |
| 149 } | 149 } |
| 150 | 150 |
| 151 // Now just release the object given the plugin var ID. | 151 // Now just release the object given the plugin var ID. |
| 152 ReleaseVar(found->second); | 152 ReleaseVar(found->second); |
| 153 } | 153 } |
| 154 | 154 |
| 155 void PluginVarTracker::DidDeleteInstance(PP_Instance instance) { | 155 void PluginVarTracker::DidDeleteInstance(PP_Instance instance) { |
| 156 // Calling the destructors on plugin objects may in turn release other |
| 157 // objects which will mutate the map out from under us. So do a two-step |
| 158 // process of identifying the ones to delete, and then delete them. |
| 159 // |
| 156 // See the comment above user_data_to_plugin_ in the header file. We assume | 160 // See the comment above user_data_to_plugin_ in the header file. We assume |
| 157 // there aren't that many objects so a brute-force search is reasonable. | 161 // there aren't that many objects so a brute-force search is reasonable. |
| 158 UserDataToPluginImplementedVarMap::iterator i = | 162 std::vector<void*> user_data_to_delete; |
| 159 user_data_to_plugin_.begin(); | 163 for (UserDataToPluginImplementedVarMap::const_iterator i = |
| 160 while (i != user_data_to_plugin_.end()) { | 164 user_data_to_plugin_.begin(); |
| 161 if (i->second.instance == instance) { | 165 i != user_data_to_plugin_.end(); |
| 162 if (!i->second.plugin_object_id) { | 166 ++i) { |
| 163 // This object is for the freed instance and the plugin is not holding | 167 if (i->second.instance == instance) |
| 164 // any references to it. Deallocate immediately. | 168 user_data_to_delete.push_back(i->first); |
| 165 UserDataToPluginImplementedVarMap::iterator to_remove = i; | 169 } |
| 166 ++i; | 170 |
| 167 to_remove->second.ppp_class->Deallocate(to_remove->first); | 171 for (size_t i = 0; i < user_data_to_delete.size(); i++) { |
| 168 user_data_to_plugin_.erase(to_remove); | 172 UserDataToPluginImplementedVarMap::iterator found = |
| 169 } else { | 173 user_data_to_plugin_.find(user_data_to_delete[i]); |
| 170 // The plugin is holding refs to this object. We don't want to call | 174 if (found == user_data_to_plugin_.end()) |
| 171 // Deallocate since the plugin may be depending on those refs to keep | 175 continue; // Object removed from list while we were iterating. |
| 172 // its data alive. To avoid crashes in this case, just clear out the | 176 |
| 173 // instance to mark it and continue. When the plugin refs go to 0, | 177 if (!found->second.plugin_object_id) { |
| 174 // we'll notice there is no instance and call Deallocate. | 178 // This object is for the freed instance and the plugin is not holding |
| 175 i->second.instance = 0; | 179 // any references to it. Deallocate immediately. |
| 176 ++i; | 180 found->second.ppp_class->Deallocate(found->first); |
| 177 } | 181 user_data_to_plugin_.erase(found); |
| 178 } else { | 182 } else { |
| 179 ++i; | 183 // The plugin is holding refs to this object. We don't want to call |
| 184 // Deallocate since the plugin may be depending on those refs to keep |
| 185 // its data alive. To avoid crashes in this case, just clear out the |
| 186 // instance to mark it and continue. When the plugin refs go to 0, |
| 187 // we'll notice there is no instance and call Deallocate. |
| 188 found->second.instance = 0; |
| 180 } | 189 } |
| 181 } | 190 } |
| 182 } | 191 } |
| 183 | 192 |
| 184 ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { | 193 ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { |
| 185 return new PluginArrayBufferVar(size_in_bytes); | 194 return new PluginArrayBufferVar(size_in_bytes); |
| 186 } | 195 } |
| 187 | 196 |
| 188 void PluginVarTracker::PluginImplementedObjectCreated( | 197 void PluginVarTracker::PluginImplementedObjectCreated( |
| 189 PP_Instance instance, | 198 PP_Instance instance, |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 VarMap::iterator ret = live_vars_.find(found->second); | 364 VarMap::iterator ret = live_vars_.find(found->second); |
| 356 DCHECK(ret != live_vars_.end()); | 365 DCHECK(ret != live_vars_.end()); |
| 357 | 366 |
| 358 // All objects should be proxy objects. | 367 // All objects should be proxy objects. |
| 359 DCHECK(ret->second.var->AsProxyObjectVar()); | 368 DCHECK(ret->second.var->AsProxyObjectVar()); |
| 360 return scoped_refptr<ProxyObjectVar>(ret->second.var->AsProxyObjectVar()); | 369 return scoped_refptr<ProxyObjectVar>(ret->second.var->AsProxyObjectVar()); |
| 361 } | 370 } |
| 362 | 371 |
| 363 } // namesace proxy | 372 } // namesace proxy |
| 364 } // namespace ppapi | 373 } // namespace ppapi |
| OLD | NEW |