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

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

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 #ifndef PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ 5 #ifndef PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_
6 #define PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ 6 #define PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_
7 7
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 10
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
14 #include "ppapi/c/pp_stdint.h" 14 #include "ppapi/c/pp_stdint.h"
15 #include "ppapi/c/pp_var.h" 15 #include "ppapi/c/pp_var.h"
16 #include "ppapi/proxy/ppapi_proxy_export.h" 16 #include "ppapi/proxy/ppapi_proxy_export.h"
17 #include "ppapi/shared_impl/var_tracker.h" 17 #include "ppapi/shared_impl/var_tracker.h"
18 18
19 template<typename T> struct DefaultSingletonTraits; 19 template<typename T> struct DefaultSingletonTraits;
20 struct PPP_Class_Deprecated;
20 21
21 namespace ppapi { 22 namespace ppapi {
22 23
23 class ProxyObjectVar; 24 class ProxyObjectVar;
24 25
25 namespace proxy { 26 namespace proxy {
26 27
27 class PluginDispatcher; 28 class PluginDispatcher;
28 29
29 // Tracks live strings and objects in the plugin process. 30 // Tracks live strings and objects in the plugin process.
(...skipping 19 matching lines...) Expand all
49 PP_Var GetHostObject(const PP_Var& plugin_object) const; 50 PP_Var GetHostObject(const PP_Var& plugin_object) const;
50 51
51 PluginDispatcher* DispatcherForPluginObject( 52 PluginDispatcher* DispatcherForPluginObject(
52 const PP_Var& plugin_object) const; 53 const PP_Var& plugin_object) const;
53 54
54 // Like Release() but the var is identified by its host object ID (as 55 // Like Release() but the var is identified by its host object ID (as
55 // returned by GetHostObject). 56 // returned by GetHostObject).
56 void ReleaseHostObject(PluginDispatcher* dispatcher, 57 void ReleaseHostObject(PluginDispatcher* dispatcher,
57 const PP_Var& host_object); 58 const PP_Var& host_object);
58 59
60 // VarTracker public overrides.
61 void DidDeleteInstance(PP_Instance instance) OVERRIDE;
62
63 // Notification that a plugin-implemented object (PPP_Class) was created by
64 // the plugin or deallocated by WebKit over IPC.
65 void PluginImplementedObjectCreated(PP_Instance instance,
66 const PP_Var& created_var,
67 const PPP_Class_Deprecated* ppp_class,
68 void* ppp_class_data);
69 void PluginImplementedObjectDestroyed(void* ppp_class_data);
70
71 // Returns true if there is an object implemented by the plugin with the
72 // given user_data that has not been deallocated yet. Call this when
73 // receiving a scripting call to the plugin to validate that the object
74 // receiving the call is still alive (see user_data_to_plugin_ below).
75 bool IsPluginImplementedObjectAlive(void* user_data);
76
77 // Validates that the given class/user_data pair corresponds to a currently
78 // living plugin object.
79 bool ValidatePluginObjectCall(const PPP_Class_Deprecated* ppp_class,
80 void* user_data);
81
59 private: 82 private:
60 // VarTracker protected overrides. 83 // VarTracker protected overrides.
61 virtual int32 AddVarInternal(Var* var, AddVarRefMode mode) OVERRIDE; 84 virtual int32 AddVarInternal(Var* var, AddVarRefMode mode) OVERRIDE;
62 virtual void TrackedObjectGettingOneRef(VarMap::const_iterator iter) OVERRIDE; 85 virtual void TrackedObjectGettingOneRef(VarMap::const_iterator iter) OVERRIDE;
63 virtual void ObjectGettingZeroRef(VarMap::iterator iter) OVERRIDE; 86 virtual void ObjectGettingZeroRef(VarMap::iterator iter) OVERRIDE;
64 virtual bool DeleteObjectInfoIfNecessary(VarMap::iterator iter) OVERRIDE; 87 virtual bool DeleteObjectInfoIfNecessary(VarMap::iterator iter) OVERRIDE;
65 virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) OVERRIDE; 88 virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) OVERRIDE;
66 89
67 private: 90 private:
68 friend struct DefaultSingletonTraits<PluginVarTracker>; 91 friend struct DefaultSingletonTraits<PluginVarTracker>;
69 friend class PluginProxyTestHarness; 92 friend class PluginProxyTestHarness;
70 93
71 // Represents a var as received from the host. 94 // Represents a var as received from the host.
72 struct HostVar { 95 struct HostVar {
73 HostVar(PluginDispatcher* d, int32 i); 96 HostVar(PluginDispatcher* d, int32 i);
74 97
75 bool operator<(const HostVar& other) const; 98 bool operator<(const HostVar& other) const;
76 99
77 // The dispatcher that sent us this object. This is used so we know how to 100 // The dispatcher that sent us this object. This is used so we know how to
78 // send back requests on this object. 101 // send back requests on this object.
79 PluginDispatcher* dispatcher; 102 PluginDispatcher* dispatcher;
80 103
81 // The object ID that the host generated to identify the object. This is 104 // The object ID that the host generated to identify the object. This is
82 // unique only within that host: different hosts could give us different 105 // unique only within that host: different hosts could give us different
83 // objects with the same ID. 106 // objects with the same ID.
84 int32 host_object_id; 107 int32 host_object_id;
85 }; 108 };
86 109
110 struct PluginImplementedVar {
111 const PPP_Class_Deprecated* ppp_class;
112
113 // The instance that created this Var. This will be 0 if the instance has
114 // been destroyed but the object is still alive.
115 PP_Instance instance;
116
117 // Represents the plugin var ID for the var corresponding to this object.
118 // If the plugin does not have a ref to the object but it's still alive
119 // (the DOM could be holding a ref keeping it alive) this will be 0.
120 //
121 // There is an obscure corner case. If the plugin returns an object to the
122 // renderer and releases all of its refs, the object will still be alive
123 // but there will be no plugin refs. It's possible for the plugin to get
124 // this same object again through the DOM, and we'll lose the correlation
125 // between plugin implemented object and car. This means we won't know when
126 // the plugin releases its last refs and may call Deallocate when the
127 // plugin is still holding a ref.
128 //
129 // However, for the plugin to be depending on holding a ref to an object
130 // that it implements that it previously released but got again through
131 // indirect means would be extremely rare, and we only allow var scripting
132 // in limited cases anyway.
133 int32 plugin_object_id;
134 };
135
87 // Returns the existing var ID for the given object var, creating and 136 // Returns the existing var ID for the given object var, creating and
88 // assigning an ID to it if necessary. This does not affect the reference 137 // assigning an ID to it if necessary. This does not affect the reference
89 // count, so in the creation case the refcount will be 0. It's assumed in 138 // count, so in the creation case the refcount will be 0. It's assumed in
90 // this case the caller will either adjust the refcount or the 139 // this case the caller will either adjust the refcount or the
91 // track_with_no_reference_count. 140 // track_with_no_reference_count.
92 PP_Var GetOrCreateObjectVarID(ProxyObjectVar* object); 141 PP_Var GetOrCreateObjectVarID(ProxyObjectVar* object);
93 142
94 // Sends an addref or release message to the browser for the given object ID. 143 // Sends an addref or release message to the browser for the given object ID.
95 void SendAddRefObjectMsg(const ProxyObjectVar& proxy_object); 144 void SendAddRefObjectMsg(const ProxyObjectVar& proxy_object);
96 void SendReleaseObjectMsg(const ProxyObjectVar& proxy_object); 145 void SendReleaseObjectMsg(const ProxyObjectVar& proxy_object);
97 146
98 // Looks up the given host var. If we already know about it, returns a 147 // Looks up the given host var. If we already know about it, returns a
99 // reference to the already-tracked object. If it doesn't creates a new one 148 // reference to the already-tracked object. If it doesn't creates a new one
100 // and returns it. If it's created, it's not added to the map. 149 // and returns it. If it's created, it's not added to the map.
101 scoped_refptr<ProxyObjectVar> FindOrMakePluginVarFromHostVar( 150 scoped_refptr<ProxyObjectVar> FindOrMakePluginVarFromHostVar(
102 const PP_Var& var, 151 const PP_Var& var,
103 PluginDispatcher* dispatcher); 152 PluginDispatcher* dispatcher);
104 153
105 // Maps host vars in the host to IDs in the plugin process. 154 // Maps host vars in the host to IDs in the plugin process.
106 typedef std::map<HostVar, int32> HostVarToPluginVarMap; 155 typedef std::map<HostVar, int32> HostVarToPluginVarMap;
107 HostVarToPluginVarMap host_var_to_plugin_var_; 156 HostVarToPluginVarMap host_var_to_plugin_var_;
108 157
158 // Maps "user data" for plugin implemented objects (PPP_Class) that are
159 // alive to various tracking info.
160 //
161 // This is tricky because there may not actually be any vars in the plugin
162 // associated with a plugin-implemented object, so they won't all have
163 // entries in our HostVarToPluginVarMap or the base class VarTracker's map.
164 //
165 // All objects that the plugin has created using CreateObject that have not
166 // yet been Deallocate()-ed by WebKit will be in this map. When the instance
167 // that created the object goes away, we know to call Deallocate on all
168 // remaining objects for that instance so that the data backing the object
169 // that the plugin owns is not leaked. We may not receive normal Deallocate
170 // calls from WebKit because the object could be leaked (attached to the DOM
171 // and outliving the plugin instance) or WebKit could send the deallocate
172 // after the out-of-process routing for that instance was torn down.
173 //
174 // There is an additional complexity. In WebKit, objects created by the
175 // plugin aren't actually bound to the plugin instance (for example, you
176 // could attach it to the DOM or send it to another plugin instance). It's
177 // possible that we could force deallocate an object when an instance id
178 // destroyed, but then another instance could get to that object somehow
179 // (like by reading it out of the DOM). We will then have deallocated the
180 // object and can't complete the call. We do not care about this case, and
181 // the calls will just fail.
182 typedef std::map<void*, PluginImplementedVar>
183 UserDataToPluginImplementedVarMap;
184 UserDataToPluginImplementedVarMap user_data_to_plugin_;
185
109 DISALLOW_COPY_AND_ASSIGN(PluginVarTracker); 186 DISALLOW_COPY_AND_ASSIGN(PluginVarTracker);
110 }; 187 };
111 188
112 } // namespace proxy 189 } // namespace proxy
113 } // namespace ppapi 190 } // namespace ppapi
114 191
115 #endif // PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ 192 #endif // PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698