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

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
« no previous file with comments | « ppapi/proxy/plugin_var_tracker.h ('k') | ppapi/proxy/plugin_var_tracker_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/dev/ppp_class_deprecated.h"
9 #include "ppapi/c/ppb_var.h" 10 #include "ppapi/c/ppb_var.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 {
(...skipping 125 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 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
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
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
OLDNEW
« no previous file with comments | « ppapi/proxy/plugin_var_tracker.h ('k') | ppapi/proxy/plugin_var_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698