1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBKIT_PLUGINS_PPAPI_RESOURCE_TRACKER_H_
#define WEBKIT_PLUGINS_PPAPI_RESOURCE_TRACKER_H_
#include <map>
#include <set>
#include <utility>
#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "base/hash_tables.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_module.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/proxy/interface_id.h"
#include "ppapi/shared_impl/function_group_base.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/shared_impl/tracker_base.h"
#include "ppapi/shared_impl/var_tracker.h"
typedef struct NPObject NPObject;
namespace ppapi {
class NPObjectVar;
class Var;
}
namespace webkit {
namespace ppapi {
class PluginInstance;
class PluginModule;
class ResourceTrackerTest;
// This class maintains a global list of all live pepper resources. It allows
// us to check resource ID validity and to map them to a specific module.
//
// This object is NOT threadsafe.
class ResourceTracker : public ::ppapi::TrackerBase,
public ::ppapi::ResourceTracker {
public:
// Returns the pointer to the singleton object.
static ResourceTracker* Get();
// PP_Resources --------------------------------------------------------------
// TrackerBase.
virtual ::ppapi::FunctionGroupBase* GetFunctionAPI(
PP_Instance pp_instance,
::ppapi::proxy::InterfaceID id) OVERRIDE;
virtual ::ppapi::VarTracker* GetVarTracker() OVERRIDE;
virtual ::ppapi::ResourceTracker* GetResourceTracker() OVERRIDE;
virtual PP_Module GetModuleForInstance(PP_Instance instance) OVERRIDE;
// ppapi::ResourceTracker overrides.
virtual void LastPluginRefWasDeleted(::ppapi::Resource* object) OVERRIDE;
// PP_Vars -------------------------------------------------------------------
// Tracks all live NPObjectVar. This is so we can map between instance +
// NPObject and get the NPObjectVar corresponding to it. This Add/Remove
// function is called by the NPObjectVar when it is created and
// destroyed.
void AddNPObjectVar(::ppapi::NPObjectVar* object_var);
void RemoveNPObjectVar(::ppapi::NPObjectVar* object_var);
// Looks up a previously registered NPObjectVar for the given NPObject and
// instance. Returns NULL if there is no NPObjectVar corresponding to the
// given NPObject for the given instance. See AddNPObjectVar above.
::ppapi::NPObjectVar* NPObjectVarForNPObject(PP_Instance instance,
NPObject* np_object);
// Returns the number of NPObjectVar's associated with the given instance.
// Returns 0 if the instance isn't known.
int GetLiveNPObjectVarsForInstance(PP_Instance instance) const;
// PP_Modules ----------------------------------------------------------------
// Adds a new plugin module to the list of tracked module, and returns a new
// module handle to identify it.
PP_Module AddModule(PluginModule* module);
// Called when a plugin modulde was deleted and should no longer be tracked.
// The given handle should be one generated by AddModule.
void ModuleDeleted(PP_Module module);
// Returns a pointer to the plugin modulde object associated with the given
// modulde handle. The return value will be NULL if the handle is invalid.
PluginModule* GetModule(PP_Module module);
// PP_Instances --------------------------------------------------------------
// Adds a new plugin instance to the list of tracked instances, and returns a
// new instance handle to identify it.
PP_Instance AddInstance(PluginInstance* instance);
// Called when a plugin instance was deleted and should no longer be tracked.
// The given handle should be one generated by AddInstance.
void InstanceDeleted(PP_Instance instance);
void InstanceCrashed(PP_Instance instance);
// Returns a pointer to the plugin instance object associated with the given
// instance handle. The return value will be NULL if the handle is invalid or
// if the instance has crashed.
PluginInstance* GetInstance(PP_Instance instance);
private:
friend class ResourceTrackerTest;
typedef std::set<PP_Resource> ResourceSet;
// Per-instance data we track.
struct InstanceData;
// Prohibit creation other then by the Singleton class.
ResourceTracker();
virtual ~ResourceTracker();
// Force frees all vars and resources associated with the given instance.
// If delete_instance is true, the instance tracking information will also
// be deleted.
void CleanupInstanceData(PP_Instance instance, bool delete_instance);
// Overrides the singleton object. This is used for tests which want to
// specify their own tracker (otherwise, you can get cross-talk between
// tests since the data will live into the subsequent tests).
static void SetSingletonOverride(ResourceTracker* tracker);
static void ClearSingletonOverride();
// The lazy-initialized global instance of this object. This is created in
// ::Get() if there is no singleton_override_ specified.
//
// It would be nice to use LazyInstance for this since it manages the
// creation properly, and also cleans up on shutdown. However, the shutdown
// cleanup causes problems in some cases.
//
// For example, say the browser crashes or is killed. The renderer then
// decides to exit. Normally resources are bound to an instance and are
// cleaned up when WebKit deletes the instance (when you go to a different
// page or close that view). In this case, WebKit doesn't clean up. If the
// ResourceTracker was cleaned up by the AtExitManager (which would be the
// case with LazyInstance/Singleton) then we'd try to call up to the renderer
// layer via the delegate, which may be in a random state of shutdown.
//
// So effectively our rule is: any resources still around at shutdown are
// associated with leaked plugins in WebKit, so it's also OK to leak those
// resources from here (avoiding the shutdown race).
static ResourceTracker* global_tracker_;
// See SetSingletonOverride above.
static ResourceTracker* singleton_override_;
::ppapi::VarTracker var_tracker_;
// Like ResourceAndRefCount but for vars, which are associated with modules.
typedef std::pair<scoped_refptr< ::ppapi::Var>, size_t> VarAndRefCount;
typedef base::hash_map<int32, VarAndRefCount> VarMap;
VarMap live_vars_;
// Tracks all live instances and their associated data.
typedef std::map<PP_Instance, linked_ptr<InstanceData> > InstanceMap;
InstanceMap instance_map_;
// Tracks all live modules. The pointers are non-owning, the PluginModule
// destructor will notify us when the module is deleted.
typedef std::map<PP_Module, PluginModule*> ModuleMap;
ModuleMap module_map_;
DISALLOW_COPY_AND_ASSIGN(ResourceTracker);
};
} // namespace ppapi
} // namespace webkit
#endif // WEBKIT_PLUGINS_PPAPI_RESOURCE_TRACKER_H_
|