Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: ppapi/proxy/plugin_var_tracker.cc

Issue 10542150: Actually free plugin implement vars when running out of process when the (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
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
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 next = i;
viettrungluu 2012/06/15 21:45:24 I think it'd be clearer if you did: ...::iterator
166 ++next;
167 i->second.ppp_class->Deallocate(i->first);
168 user_data_to_plugin_.erase(i);
169 i = next;
170 } else {
171 // The plugin is holding refs to this object. We don't want to call
172 // Deallocate since the plugin may be depending on those refs to keep
173 // its data alive. To avoid crashes in this case, just clear out the
174 // instance to mark it and continue. When the plugin refs go to 0,
175 // we'll notice there is no instance and call Deallocate.
176 i->second.instance = 0;
177 ++i;
178 }
179 } else {
180 ++i;
181 }
182 }
183 }
184
154 ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { 185 ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) {
155 return new PluginArrayBufferVar(size_in_bytes); 186 return new PluginArrayBufferVar(size_in_bytes);
156 } 187 }
157 188
189 void PluginVarTracker::PluginImplementedObjectCreated(
190 PP_Instance instance,
191 const PP_Var& created_var,
192 const PPP_Class_Deprecated* ppp_class,
193 void* ppp_class_data) {
194 PluginImplementedVar p;
195 p.ppp_class = ppp_class;
196 p.instance = instance;
197 p.plugin_object_id = created_var.value.as_id;
198 user_data_to_plugin_[ppp_class_data] = p;
199
200 // Link the user data to the object.
201 ProxyObjectVar* object = GetVar(created_var)->AsProxyObjectVar();
202 object->set_user_data(ppp_class_data);
203 }
204
205 void PluginVarTracker::PluginImplementedObjectDestroyed(void* user_data) {
206 UserDataToPluginImplementedVarMap::iterator found =
207 user_data_to_plugin_.find(user_data);
208 if (found == user_data_to_plugin_.end()) {
209 NOTREACHED();
210 return;
211 }
212 user_data_to_plugin_.erase(found);
213 }
214
215 bool PluginVarTracker::IsPluginImplementedObjectAlive(void* user_data) {
216 return user_data_to_plugin_.find(user_data) != user_data_to_plugin_.end();
217 }
218
219 bool PluginVarTracker::ValidatePluginObjectCall(
220 const PPP_Class_Deprecated* ppp_class,
221 void* user_data) {
222 UserDataToPluginImplementedVarMap::iterator found =
223 user_data_to_plugin_.find(user_data);
224 if (found == user_data_to_plugin_.end())
225 return false;
226 return found->second.ppp_class == ppp_class;
227 }
228
158 int32 PluginVarTracker::AddVarInternal(Var* var, AddVarRefMode mode) { 229 int32 PluginVarTracker::AddVarInternal(Var* var, AddVarRefMode mode) {
159 // Normal adding. 230 // Normal adding.
160 int32 new_id = VarTracker::AddVarInternal(var, mode); 231 int32 new_id = VarTracker::AddVarInternal(var, mode);
161 232
162 // Need to add proxy objects to the host var map. 233 // Need to add proxy objects to the host var map.
163 ProxyObjectVar* proxy_object = var->AsProxyObjectVar(); 234 ProxyObjectVar* proxy_object = var->AsProxyObjectVar();
164 if (proxy_object) { 235 if (proxy_object) {
165 HostVar host_var(proxy_object->dispatcher(), proxy_object->host_var_id()); 236 HostVar host_var(proxy_object->dispatcher(), proxy_object->host_var_id());
166 DCHECK(host_var_to_plugin_var_.find(host_var) == 237 DCHECK(host_var_to_plugin_var_.find(host_var) ==
167 host_var_to_plugin_var_.end()); // Adding an object twice, use 238 host_var_to_plugin_var_.end()); // Adding an object twice, use
(...skipping 25 matching lines...) Expand all
193 ProxyObjectVar* object = iter->second.var->AsProxyObjectVar(); 264 ProxyObjectVar* object = iter->second.var->AsProxyObjectVar();
194 if (!object) { 265 if (!object) {
195 NOTREACHED(); 266 NOTREACHED();
196 return; 267 return;
197 } 268 }
198 269
199 // Notify the host we're no longer holding our ref. 270 // Notify the host we're no longer holding our ref.
200 DCHECK(iter->second.ref_count == 0); 271 DCHECK(iter->second.ref_count == 0);
201 SendReleaseObjectMsg(*object); 272 SendReleaseObjectMsg(*object);
202 273
274 UserDataToPluginImplementedVarMap::iterator found =
275 user_data_to_plugin_.find(object->user_data());
276 if (found != user_data_to_plugin_.end()) {
277 // This object is implemented in the plugin.
278 if (found->second.instance == 0) {
279 // Instance is destroyed. This means that we'll never get a Deallocate
280 // call from the renderer and we should do so now.
281 found->second.ppp_class->Deallocate(found->first);
282 user_data_to_plugin_.erase(found);
283 } else {
284 // The plugin is releasing its last reference to an object it implements.
285 // Clear the tracking data that links our "plugin implemented object" to
286 // the var. If the instance is destroyed and there is no ID, we know that
287 // we should just call Deallocate on the object data.
288 //
289 // See the plugin_object_id declaration for more info.
290 found->second.plugin_object_id = 0;
291 }
292 }
293
203 // This will optionally delete the info from live_vars_. 294 // This will optionally delete the info from live_vars_.
204 VarTracker::ObjectGettingZeroRef(iter); 295 VarTracker::ObjectGettingZeroRef(iter);
205 } 296 }
206 297
207 bool PluginVarTracker::DeleteObjectInfoIfNecessary(VarMap::iterator iter) { 298 bool PluginVarTracker::DeleteObjectInfoIfNecessary(VarMap::iterator iter) {
208 // Get the info before calling the base class's version of this function, 299 // Get the info before calling the base class's version of this function,
209 // which may delete the object. 300 // which may delete the object.
210 ProxyObjectVar* object = iter->second.var->AsProxyObjectVar(); 301 ProxyObjectVar* object = iter->second.var->AsProxyObjectVar();
211 HostVar host_var(object->dispatcher(), object->host_var_id()); 302 HostVar host_var(object->dispatcher(), object->host_var_id());
212 303
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 VarMap::iterator ret = live_vars_.find(found->second); 356 VarMap::iterator ret = live_vars_.find(found->second);
266 DCHECK(ret != live_vars_.end()); 357 DCHECK(ret != live_vars_.end());
267 358
268 // All objects should be proxy objects. 359 // All objects should be proxy objects.
269 DCHECK(ret->second.var->AsProxyObjectVar()); 360 DCHECK(ret->second.var->AsProxyObjectVar());
270 return scoped_refptr<ProxyObjectVar>(ret->second.var->AsProxyObjectVar()); 361 return scoped_refptr<ProxyObjectVar>(ret->second.var->AsProxyObjectVar());
271 } 362 }
272 363
273 } // namesace proxy 364 } // namesace proxy
274 } // namespace ppapi 365 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698