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 |