| 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/proxy/plugin_var_tracker.h" | 5 #include "ppapi/proxy/plugin_var_tracker.h" |
| 6 | 6 |
| 7 #include "base/ref_counted.h" | 7 #include "base/ref_counted.h" |
| 8 #include "base/singleton.h" | 8 #include "base/singleton.h" |
| 9 #include "ppapi/c/ppb_var.h" | 9 #include "ppapi/c/ppb_var.h" |
| 10 #include "ppapi/proxy/plugin_dispatcher.h" |
| 10 #include "ppapi/proxy/ppapi_messages.h" | 11 #include "ppapi/proxy/ppapi_messages.h" |
| 11 #include "ppapi/proxy/interface_id.h" | 12 #include "ppapi/proxy/interface_id.h" |
| 12 | 13 |
| 13 namespace pp { | 14 namespace pp { |
| 14 namespace proxy { | 15 namespace proxy { |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 // When non-NULL, this object overrides the VarTrackerSingleton. | 19 // When non-NULL, this object overrides the VarTrackerSingleton. |
| 19 PluginVarTracker* var_tracker_override = NULL; | 20 PluginVarTracker* var_tracker_override = NULL; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 35 }; | 36 }; |
| 36 | 37 |
| 37 // When running in the plugin, this will convert the string ID to the object | 38 // When running in the plugin, this will convert the string ID to the object |
| 38 // using casting. No validity checking is done. | 39 // using casting. No validity checking is done. |
| 39 RefCountedString* PluginStringFromID(PluginVarTracker::VarID id) { | 40 RefCountedString* PluginStringFromID(PluginVarTracker::VarID id) { |
| 40 return reinterpret_cast<RefCountedString*>(static_cast<intptr_t>(id)); | 41 return reinterpret_cast<RefCountedString*>(static_cast<intptr_t>(id)); |
| 41 } | 42 } |
| 42 | 43 |
| 43 } // namespace | 44 } // namespace |
| 44 | 45 |
| 45 PluginVarTracker::HostVar::HostVar(Sender* d, VarID i) | 46 PluginVarTracker::HostVar::HostVar(PluginDispatcher* d, VarID i) |
| 46 : channel(d), | 47 : dispatcher(d), |
| 47 host_object_id(i) { | 48 host_object_id(i) { |
| 48 } | 49 } |
| 49 | 50 |
| 50 bool PluginVarTracker::HostVar::operator<(const HostVar& other) const { | 51 bool PluginVarTracker::HostVar::operator<(const HostVar& other) const { |
| 51 if (channel < other.channel) | 52 if (dispatcher < other.dispatcher) |
| 52 return true; | 53 return true; |
| 53 if (other.channel < channel) | 54 if (other.dispatcher < dispatcher) |
| 54 return false; | 55 return false; |
| 55 return host_object_id < other.host_object_id; | 56 return host_object_id < other.host_object_id; |
| 56 } | 57 } |
| 57 | 58 |
| 58 PluginVarTracker::PluginVarInfo::PluginVarInfo(const HostVar& host_var) | 59 PluginVarTracker::PluginVarInfo::PluginVarInfo(const HostVar& host_var) |
| 59 : host_var(host_var), | 60 : host_var(host_var), |
| 60 ref_count(0), | 61 ref_count(0), |
| 61 track_with_no_reference_count(0) { | 62 track_with_no_reference_count(0) { |
| 62 } | 63 } |
| 63 | 64 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } | 143 } |
| 143 | 144 |
| 144 info.ref_count--; | 145 info.ref_count--; |
| 145 if (info.ref_count == 0) | 146 if (info.ref_count == 0) |
| 146 SendReleaseObjectMsg(info.host_var); | 147 SendReleaseObjectMsg(info.host_var); |
| 147 DeletePluginVarInfoIfNecessary(found); | 148 DeletePluginVarInfoIfNecessary(found); |
| 148 } | 149 } |
| 149 } | 150 } |
| 150 | 151 |
| 151 PP_Var PluginVarTracker::ReceiveObjectPassRef(const PP_Var& var, | 152 PP_Var PluginVarTracker::ReceiveObjectPassRef(const PP_Var& var, |
| 152 Sender* channel) { | 153 PluginDispatcher* dispatcher) { |
| 153 DCHECK(var.type == PP_VARTYPE_OBJECT); | 154 DCHECK(var.type == PP_VARTYPE_OBJECT); |
| 154 | 155 |
| 155 // Find the plugin info. | 156 // Find the plugin info. |
| 156 PluginVarInfoMap::iterator found = | 157 PluginVarInfoMap::iterator found = |
| 157 FindOrMakePluginVarFromHostVar(var, channel); | 158 FindOrMakePluginVarFromHostVar(var, dispatcher); |
| 158 if (found == plugin_var_info_.end()) { | 159 if (found == plugin_var_info_.end()) { |
| 159 // The above code should have always made an entry in the map. | 160 // The above code should have always made an entry in the map. |
| 160 NOTREACHED(); | 161 NOTREACHED(); |
| 161 return PP_MakeUndefined(); | 162 return PP_MakeUndefined(); |
| 162 } | 163 } |
| 163 | 164 |
| 164 // Fix up the references. The host (renderer) just sent us a ref. The | 165 // Fix up the references. The host (renderer) just sent us a ref. The |
| 165 // renderer has addrefed the var in its tracker for us since it's returning | 166 // renderer has addrefed the var in its tracker for us since it's returning |
| 166 // it. | 167 // it. |
| 167 PluginVarInfo& info = found->second; | 168 PluginVarInfo& info = found->second; |
| 168 if (info.ref_count == 0) { | 169 if (info.ref_count == 0) { |
| 169 // We don't have a reference to this already, then we just add it to our | 170 // We don't have a reference to this already, then we just add it to our |
| 170 // tracker and use that one ref. | 171 // tracker and use that one ref. |
| 171 info.ref_count = 1; | 172 info.ref_count = 1; |
| 172 } else { | 173 } else { |
| 173 // We already have a reference to it, that means the renderer now has two | 174 // We already have a reference to it, that means the renderer now has two |
| 174 // references on our behalf. We want to transfer that extra reference to | 175 // references on our behalf. We want to transfer that extra reference to |
| 175 // our list. This means we addref in the plugin, and release the extra one | 176 // our list. This means we addref in the plugin, and release the extra one |
| 176 // in the renderer. | 177 // in the renderer. |
| 177 SendReleaseObjectMsg(info.host_var); | 178 SendReleaseObjectMsg(info.host_var); |
| 178 info.ref_count++; | 179 info.ref_count++; |
| 179 } | 180 } |
| 180 | 181 |
| 181 PP_Var ret; | 182 PP_Var ret; |
| 182 ret.type = PP_VARTYPE_OBJECT; | 183 ret.type = PP_VARTYPE_OBJECT; |
| 183 ret.value.as_id = found->first; | 184 ret.value.as_id = found->first; |
| 184 return ret; | 185 return ret; |
| 185 } | 186 } |
| 186 | 187 |
| 187 PP_Var PluginVarTracker::TrackObjectWithNoReference(const PP_Var& host_var, | 188 PP_Var PluginVarTracker::TrackObjectWithNoReference( |
| 188 Sender* channel) { | 189 const PP_Var& host_var, |
| 190 PluginDispatcher* dispatcher) { |
| 189 DCHECK(host_var.type == PP_VARTYPE_OBJECT); | 191 DCHECK(host_var.type == PP_VARTYPE_OBJECT); |
| 190 | 192 |
| 191 PluginVarInfoMap::iterator found = | 193 PluginVarInfoMap::iterator found = |
| 192 FindOrMakePluginVarFromHostVar(host_var, channel); | 194 FindOrMakePluginVarFromHostVar(host_var, dispatcher); |
| 193 if (found == plugin_var_info_.end()) { | 195 if (found == plugin_var_info_.end()) { |
| 194 // The above code should have always made an entry in the map. | 196 // The above code should have always made an entry in the map. |
| 195 NOTREACHED(); | 197 NOTREACHED(); |
| 196 return PP_MakeUndefined(); | 198 return PP_MakeUndefined(); |
| 197 } | 199 } |
| 198 | 200 |
| 199 found->second.track_with_no_reference_count++; | 201 found->second.track_with_no_reference_count++; |
| 200 | 202 |
| 201 PP_Var ret; | 203 PP_Var ret; |
| 202 ret.type = PP_VARTYPE_OBJECT; | 204 ret.type = PP_VARTYPE_OBJECT; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 225 if (found == plugin_var_info_.end()) { | 227 if (found == plugin_var_info_.end()) { |
| 226 NOTREACHED(); | 228 NOTREACHED(); |
| 227 return PP_MakeUndefined(); | 229 return PP_MakeUndefined(); |
| 228 } | 230 } |
| 229 PP_Var ret; | 231 PP_Var ret; |
| 230 ret.type = PP_VARTYPE_OBJECT; | 232 ret.type = PP_VARTYPE_OBJECT; |
| 231 ret.value.as_id = found->second.host_var.host_object_id; | 233 ret.value.as_id = found->second.host_var.host_object_id; |
| 232 return ret; | 234 return ret; |
| 233 } | 235 } |
| 234 | 236 |
| 235 void PluginVarTracker::ReleaseHostObject(Sender* sender, | 237 PluginDispatcher* PluginVarTracker::DispatcherForPluginObject( |
| 238 const PP_Var& plugin_object) const { |
| 239 DCHECK(plugin_object.type == PP_VARTYPE_OBJECT); |
| 240 PluginVarInfoMap::const_iterator found = plugin_var_info_.find( |
| 241 plugin_object.value.as_id); |
| 242 if (found != plugin_var_info_.end()) |
| 243 return found->second.host_var.dispatcher; |
| 244 return NULL; |
| 245 } |
| 246 |
| 247 void PluginVarTracker::ReleaseHostObject(PluginDispatcher* dispatcher, |
| 236 const PP_Var& host_object) { | 248 const PP_Var& host_object) { |
| 237 // Convert the host object to a normal var valid in the plugin. | 249 // Convert the host object to a normal var valid in the plugin. |
| 238 DCHECK(host_object.type == PP_VARTYPE_OBJECT); | 250 DCHECK(host_object.type == PP_VARTYPE_OBJECT); |
| 239 HostVarToPluginVarMap::iterator found = host_var_to_plugin_var_.find( | 251 HostVarToPluginVarMap::iterator found = host_var_to_plugin_var_.find( |
| 240 HostVar(sender, host_object.value.as_id)); | 252 HostVar(dispatcher, host_object.value.as_id)); |
| 241 if (found == host_var_to_plugin_var_.end()) { | 253 if (found == host_var_to_plugin_var_.end()) { |
| 242 NOTREACHED(); | 254 NOTREACHED(); |
| 243 return; | 255 return; |
| 244 } | 256 } |
| 245 | 257 |
| 246 // Now just release the object like normal. | 258 // Now just release the object like normal. |
| 247 PP_Var plugin_object; | 259 PP_Var plugin_object; |
| 248 plugin_object.type = PP_VARTYPE_OBJECT; | 260 plugin_object.type = PP_VARTYPE_OBJECT; |
| 249 plugin_object.value.as_id = found->second; | 261 plugin_object.value.as_id = found->second; |
| 250 Release(plugin_object); | 262 Release(plugin_object); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 261 int PluginVarTracker::GetTrackedWithNoReferenceCountForObject( | 273 int PluginVarTracker::GetTrackedWithNoReferenceCountForObject( |
| 262 const PP_Var& plugin_object) { | 274 const PP_Var& plugin_object) { |
| 263 PluginVarInfoMap::iterator found = plugin_var_info_.find( | 275 PluginVarInfoMap::iterator found = plugin_var_info_.find( |
| 264 plugin_object.value.as_id); | 276 plugin_object.value.as_id); |
| 265 if (found == plugin_var_info_.end()) | 277 if (found == plugin_var_info_.end()) |
| 266 return -1; | 278 return -1; |
| 267 return found->second.track_with_no_reference_count; | 279 return found->second.track_with_no_reference_count; |
| 268 } | 280 } |
| 269 | 281 |
| 270 void PluginVarTracker::SendAddRefObjectMsg(const HostVar& host_var) { | 282 void PluginVarTracker::SendAddRefObjectMsg(const HostVar& host_var) { |
| 271 host_var.channel->Send(new PpapiHostMsg_PPBVar_AddRefObject( | 283 host_var.dispatcher->Send(new PpapiHostMsg_PPBVar_AddRefObject( |
| 272 INTERFACE_ID_PPB_VAR_DEPRECATED, host_var.host_object_id)); | 284 INTERFACE_ID_PPB_VAR_DEPRECATED, host_var.host_object_id)); |
| 273 } | 285 } |
| 274 | 286 |
| 275 void PluginVarTracker::SendReleaseObjectMsg(const HostVar& host_var) { | 287 void PluginVarTracker::SendReleaseObjectMsg(const HostVar& host_var) { |
| 276 host_var.channel->Send(new PpapiHostMsg_PPBVar_ReleaseObject( | 288 host_var.dispatcher->Send(new PpapiHostMsg_PPBVar_ReleaseObject( |
| 277 INTERFACE_ID_PPB_VAR_DEPRECATED, host_var.host_object_id)); | 289 INTERFACE_ID_PPB_VAR_DEPRECATED, host_var.host_object_id)); |
| 278 } | 290 } |
| 279 | 291 |
| 280 PluginVarTracker::PluginVarInfoMap::iterator | 292 PluginVarTracker::PluginVarInfoMap::iterator |
| 281 PluginVarTracker::FindOrMakePluginVarFromHostVar(const PP_Var& var, | 293 PluginVarTracker::FindOrMakePluginVarFromHostVar(const PP_Var& var, |
| 282 Sender* channel) { | 294 PluginDispatcher* dispatcher) { |
| 283 DCHECK(var.type == PP_VARTYPE_OBJECT); | 295 DCHECK(var.type == PP_VARTYPE_OBJECT); |
| 284 HostVar host_var(channel, var.value.as_id); | 296 HostVar host_var(dispatcher, var.value.as_id); |
| 285 | 297 |
| 286 HostVarToPluginVarMap::iterator found = | 298 HostVarToPluginVarMap::iterator found = |
| 287 host_var_to_plugin_var_.find(host_var); | 299 host_var_to_plugin_var_.find(host_var); |
| 288 if (found != host_var_to_plugin_var_.end()) { | 300 if (found != host_var_to_plugin_var_.end()) { |
| 289 PluginVarInfoMap::iterator ret = plugin_var_info_.find(found->second); | 301 PluginVarInfoMap::iterator ret = plugin_var_info_.find(found->second); |
| 290 DCHECK(ret != plugin_var_info_.end()); | 302 DCHECK(ret != plugin_var_info_.end()); |
| 291 return ret; // Already know about this var return the ID. | 303 return ret; // Already know about this var return the ID. |
| 292 } | 304 } |
| 293 | 305 |
| 294 // Make a new var, adding references to both maps. | 306 // Make a new var, adding references to both maps. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 306 | 318 |
| 307 // Object ref counts are all zero, delete from both maps. | 319 // Object ref counts are all zero, delete from both maps. |
| 308 DCHECK(host_var_to_plugin_var_.find(iter->second.host_var) != | 320 DCHECK(host_var_to_plugin_var_.find(iter->second.host_var) != |
| 309 host_var_to_plugin_var_.end()); | 321 host_var_to_plugin_var_.end()); |
| 310 host_var_to_plugin_var_.erase(iter->second.host_var); | 322 host_var_to_plugin_var_.erase(iter->second.host_var); |
| 311 plugin_var_info_.erase(iter); | 323 plugin_var_info_.erase(iter); |
| 312 } | 324 } |
| 313 | 325 |
| 314 } // namesace proxy | 326 } // namesace proxy |
| 315 } // namespace pp | 327 } // namespace pp |
| OLD | NEW |