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/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/ppb_var.h" | 9 #include "ppapi/c/ppb_var.h" |
| 10 #include "ppapi/c/dev/ppp_class_deprecated.h" | |
|
viettrungluu
2012/06/15 22:04:15
But wait, there's more! Lint tells us that this is
| |
| 10 #include "ppapi/proxy/plugin_array_buffer_var.h" | 11 #include "ppapi/proxy/plugin_array_buffer_var.h" |
| 11 #include "ppapi/proxy/plugin_dispatcher.h" | 12 #include "ppapi/proxy/plugin_dispatcher.h" |
| 12 #include "ppapi/proxy/ppapi_messages.h" | 13 #include "ppapi/proxy/ppapi_messages.h" |
| 13 #include "ppapi/proxy/proxy_object_var.h" | 14 #include "ppapi/proxy/proxy_object_var.h" |
| 14 #include "ppapi/shared_impl/api_id.h" | 15 #include "ppapi/shared_impl/api_id.h" |
| 15 #include "ppapi/shared_impl/var.h" | 16 #include "ppapi/shared_impl/var.h" |
| 16 | 17 |
| 17 namespace ppapi { | 18 namespace ppapi { |
| 18 namespace proxy { | 19 namespace proxy { |
| 19 | 20 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 HostVar(dispatcher, static_cast<int32>(host_object.value.as_id))); | 145 HostVar(dispatcher, static_cast<int32>(host_object.value.as_id))); |
| 145 if (found == host_var_to_plugin_var_.end()) { | 146 if (found == host_var_to_plugin_var_.end()) { |
| 146 NOTREACHED(); | 147 NOTREACHED(); |
| 147 return; | 148 return; |
| 148 } | 149 } |
| 149 | 150 |
| 150 // Now just release the object given the plugin var ID. | 151 // Now just release the object given the plugin var ID. |
| 151 ReleaseVar(found->second); | 152 ReleaseVar(found->second); |
| 152 } | 153 } |
| 153 | 154 |
| 155 void PluginVarTracker::DidDeleteInstance(PP_Instance instance) { | |
| 156 // 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. | |
| 158 UserDataToPluginImplementedVarMap::iterator i = | |
| 159 user_data_to_plugin_.begin(); | |
| 160 while (i != user_data_to_plugin_.end()) { | |
| 161 if (i->second.instance == instance) { | |
| 162 if (!i->second.plugin_object_id) { | |
| 163 // This object is for the freed instance and the plugin is not holding | |
| 164 // any references to it. Deallocate immediately. | |
| 165 UserDataToPluginImplementedVarMap::iterator to_remove = i; | |
| 166 ++i; | |
| 167 to_remove->second.ppp_class->Deallocate(to_remove->first); | |
| 168 user_data_to_plugin_.erase(to_remove); | |
| 169 } else { | |
| 170 // The plugin is holding refs to this object. We don't want to call | |
| 171 // Deallocate since the plugin may be depending on those refs to keep | |
| 172 // its data alive. To avoid crashes in this case, just clear out the | |
| 173 // instance to mark it and continue. When the plugin refs go to 0, | |
| 174 // we'll notice there is no instance and call Deallocate. | |
| 175 i->second.instance = 0; | |
| 176 ++i; | |
| 177 } | |
| 178 } else { | |
| 179 ++i; | |
| 180 } | |
| 181 } | |
| 182 } | |
| 183 | |
| 154 ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { | 184 ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { |
| 155 return new PluginArrayBufferVar(size_in_bytes); | 185 return new PluginArrayBufferVar(size_in_bytes); |
| 156 } | 186 } |
| 157 | 187 |
| 188 void PluginVarTracker::PluginImplementedObjectCreated( | |
| 189 PP_Instance instance, | |
| 190 const PP_Var& created_var, | |
| 191 const PPP_Class_Deprecated* ppp_class, | |
| 192 void* ppp_class_data) { | |
| 193 PluginImplementedVar p; | |
| 194 p.ppp_class = ppp_class; | |
| 195 p.instance = instance; | |
| 196 p.plugin_object_id = created_var.value.as_id; | |
| 197 user_data_to_plugin_[ppp_class_data] = p; | |
| 198 | |
| 199 // Link the user data to the object. | |
| 200 ProxyObjectVar* object = GetVar(created_var)->AsProxyObjectVar(); | |
| 201 object->set_user_data(ppp_class_data); | |
| 202 } | |
| 203 | |
| 204 void PluginVarTracker::PluginImplementedObjectDestroyed(void* user_data) { | |
| 205 UserDataToPluginImplementedVarMap::iterator found = | |
| 206 user_data_to_plugin_.find(user_data); | |
| 207 if (found == user_data_to_plugin_.end()) { | |
| 208 NOTREACHED(); | |
| 209 return; | |
| 210 } | |
| 211 user_data_to_plugin_.erase(found); | |
| 212 } | |
| 213 | |
| 214 bool PluginVarTracker::IsPluginImplementedObjectAlive(void* user_data) { | |
| 215 return user_data_to_plugin_.find(user_data) != user_data_to_plugin_.end(); | |
| 216 } | |
| 217 | |
| 218 bool PluginVarTracker::ValidatePluginObjectCall( | |
| 219 const PPP_Class_Deprecated* ppp_class, | |
| 220 void* user_data) { | |
| 221 UserDataToPluginImplementedVarMap::iterator found = | |
| 222 user_data_to_plugin_.find(user_data); | |
| 223 if (found == user_data_to_plugin_.end()) | |
| 224 return false; | |
| 225 return found->second.ppp_class == ppp_class; | |
| 226 } | |
| 227 | |
| 158 int32 PluginVarTracker::AddVarInternal(Var* var, AddVarRefMode mode) { | 228 int32 PluginVarTracker::AddVarInternal(Var* var, AddVarRefMode mode) { |
| 159 // Normal adding. | 229 // Normal adding. |
| 160 int32 new_id = VarTracker::AddVarInternal(var, mode); | 230 int32 new_id = VarTracker::AddVarInternal(var, mode); |
| 161 | 231 |
| 162 // Need to add proxy objects to the host var map. | 232 // Need to add proxy objects to the host var map. |
| 163 ProxyObjectVar* proxy_object = var->AsProxyObjectVar(); | 233 ProxyObjectVar* proxy_object = var->AsProxyObjectVar(); |
| 164 if (proxy_object) { | 234 if (proxy_object) { |
| 165 HostVar host_var(proxy_object->dispatcher(), proxy_object->host_var_id()); | 235 HostVar host_var(proxy_object->dispatcher(), proxy_object->host_var_id()); |
| 166 DCHECK(host_var_to_plugin_var_.find(host_var) == | 236 DCHECK(host_var_to_plugin_var_.find(host_var) == |
| 167 host_var_to_plugin_var_.end()); // Adding an object twice, use | 237 host_var_to_plugin_var_.end()); // Adding an object twice, use |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 193 ProxyObjectVar* object = iter->second.var->AsProxyObjectVar(); | 263 ProxyObjectVar* object = iter->second.var->AsProxyObjectVar(); |
| 194 if (!object) { | 264 if (!object) { |
| 195 NOTREACHED(); | 265 NOTREACHED(); |
| 196 return; | 266 return; |
| 197 } | 267 } |
| 198 | 268 |
| 199 // Notify the host we're no longer holding our ref. | 269 // Notify the host we're no longer holding our ref. |
| 200 DCHECK(iter->second.ref_count == 0); | 270 DCHECK(iter->second.ref_count == 0); |
| 201 SendReleaseObjectMsg(*object); | 271 SendReleaseObjectMsg(*object); |
| 202 | 272 |
| 273 UserDataToPluginImplementedVarMap::iterator found = | |
| 274 user_data_to_plugin_.find(object->user_data()); | |
| 275 if (found != user_data_to_plugin_.end()) { | |
| 276 // This object is implemented in the plugin. | |
| 277 if (found->second.instance == 0) { | |
| 278 // Instance is destroyed. This means that we'll never get a Deallocate | |
| 279 // call from the renderer and we should do so now. | |
| 280 found->second.ppp_class->Deallocate(found->first); | |
| 281 user_data_to_plugin_.erase(found); | |
| 282 } else { | |
| 283 // The plugin is releasing its last reference to an object it implements. | |
| 284 // Clear the tracking data that links our "plugin implemented object" to | |
| 285 // the var. If the instance is destroyed and there is no ID, we know that | |
| 286 // we should just call Deallocate on the object data. | |
| 287 // | |
| 288 // See the plugin_object_id declaration for more info. | |
| 289 found->second.plugin_object_id = 0; | |
| 290 } | |
| 291 } | |
| 292 | |
| 203 // This will optionally delete the info from live_vars_. | 293 // This will optionally delete the info from live_vars_. |
| 204 VarTracker::ObjectGettingZeroRef(iter); | 294 VarTracker::ObjectGettingZeroRef(iter); |
| 205 } | 295 } |
| 206 | 296 |
| 207 bool PluginVarTracker::DeleteObjectInfoIfNecessary(VarMap::iterator iter) { | 297 bool PluginVarTracker::DeleteObjectInfoIfNecessary(VarMap::iterator iter) { |
| 208 // Get the info before calling the base class's version of this function, | 298 // Get the info before calling the base class's version of this function, |
| 209 // which may delete the object. | 299 // which may delete the object. |
| 210 ProxyObjectVar* object = iter->second.var->AsProxyObjectVar(); | 300 ProxyObjectVar* object = iter->second.var->AsProxyObjectVar(); |
| 211 HostVar host_var(object->dispatcher(), object->host_var_id()); | 301 HostVar host_var(object->dispatcher(), object->host_var_id()); |
| 212 | 302 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 VarMap::iterator ret = live_vars_.find(found->second); | 355 VarMap::iterator ret = live_vars_.find(found->second); |
| 266 DCHECK(ret != live_vars_.end()); | 356 DCHECK(ret != live_vars_.end()); |
| 267 | 357 |
| 268 // All objects should be proxy objects. | 358 // All objects should be proxy objects. |
| 269 DCHECK(ret->second.var->AsProxyObjectVar()); | 359 DCHECK(ret->second.var->AsProxyObjectVar()); |
| 270 return scoped_refptr<ProxyObjectVar>(ret->second.var->AsProxyObjectVar()); | 360 return scoped_refptr<ProxyObjectVar>(ret->second.var->AsProxyObjectVar()); |
| 271 } | 361 } |
| 272 | 362 |
| 273 } // namesace proxy | 363 } // namesace proxy |
| 274 } // namespace ppapi | 364 } // namespace ppapi |
| OLD | NEW |