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
|
// Copyright (c) 2012 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 PPAPI_SHARED_IMPL_RESOURCE_TRACKER_H_
#define PPAPI_SHARED_IMPL_RESOURCE_TRACKER_H_
#include <set>
#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_checker_impl.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/shared_impl/ppapi_shared_export.h"
namespace ppapi {
class Resource;
class PPAPI_SHARED_EXPORT ResourceTracker {
public:
// A SINGLE_THREADED ResourceTracker will use a thread-checker to make sure
// it's always invoked on the same thread on which it was constructed. A
// THREAD_SAFE ResourceTracker will check that the ProxyLock is held. See
// CheckThreadingPreconditions() for more details.
enum ThreadMode { SINGLE_THREADED, THREAD_SAFE };
explicit ResourceTracker(ThreadMode thread_mode);
virtual ~ResourceTracker();
// The returned pointer will be NULL if there is no resource. The reference
// count of the resource is unaffected.
Resource* GetResource(PP_Resource res) const;
// Takes a reference on the given resource.
// Do not call this method on on the host side for resources backed by a
// ResourceHost.
void AddRefResource(PP_Resource res);
// Releases a reference on the given resource.
// Do not call this method on on the host side for resources backed by a
// ResourceHost.
void ReleaseResource(PP_Resource res);
// Releases a reference on the given resource once the message loop returns.
void ReleaseResourceSoon(PP_Resource res);
// Notifies the tracker that a new instance has been created. This must be
// called before creating any resources associated with the instance.
void DidCreateInstance(PP_Instance instance);
// Called when an instance is being deleted. All plugin refs for the
// associated resources will be force freed, and the resources (if they still
// exist) will be disassociated from the instance.
void DidDeleteInstance(PP_Instance instance);
// Returns the number of resources associated with the given instance.
// Returns 0 if the instance isn't known.
int GetLiveObjectsForInstance(PP_Instance instance) const;
protected:
// This calls AddResource and RemoveResource.
friend class Resource;
// On the host-side, make sure we are called on the right thread. On the
// plugin side, make sure we have the proxy lock.
void CheckThreadingPreconditions() const;
// This method is called by PluginResourceTracker's constructor so that in
// debug mode PP_Resources from the plugin process always have odd values
// (ignoring the type bits), while PP_Resources from the renderer process have
// even values.
// This allows us to check that resource refs aren't added or released on the
// wrong side.
void UseOddResourceValueInDebugMode();
// Adds the given resource to the tracker, associating it with the instance
// stored in the resource object. The new resource ID is returned, and the
// resource will have 0 plugin refcount. This is called by the resource
// constructor.
//
// Returns 0 if the resource could not be added.
virtual PP_Resource AddResource(Resource* object);
// The opposite of AddResource, this removes the tracking information for
// the given resource. It's called from the resource destructor.
virtual void RemoveResource(Resource* object);
private:
// Calls NotifyLastPluginRefWasDeleted on the given resource object and
// cancels pending callbacks for the resource.
void LastPluginRefWasDeleted(Resource* object);
int32 GetNextResourceValue();
// In debug mode, checks whether |res| comes from the same resource tracker.
bool CanOperateOnResource(PP_Resource res);
typedef std::set<PP_Resource> ResourceSet;
struct InstanceData {
// Lists all resources associated with the given instance as non-owning
// pointers. This allows us to notify those resources that the instance is
// going away (otherwise, they may crash if they outlive the instance).
ResourceSet resources;
};
typedef base::hash_map<PP_Instance, linked_ptr<InstanceData> > InstanceMap;
InstanceMap instance_map_;
// For each PP_Resource, keep the object pointer and a plugin use count.
// This use count is different then Resource object's RefCount, and is
// manipulated using this AddRefResource/UnrefResource. When the plugin use
// count is positive, we keep an extra ref on the Resource on
// behalf of the plugin. When it drops to 0, we free that ref, keeping
// the resource in the list.
//
// A resource will be in this list as long as the object is alive.
typedef std::pair<Resource*, int> ResourceAndRefCount;
typedef base::hash_map<PP_Resource, ResourceAndRefCount> ResourceMap;
ResourceMap live_resources_;
int32 last_resource_value_;
// On the host side, we want to check that we are only called on the main
// thread. This is to protect us from accidentally using the tracker from
// other threads (especially the IO thread). On the plugin side, the tracker
// is protected by the proxy lock and is thread-safe, so this will be NULL.
scoped_ptr<base::ThreadChecker> thread_checker_;
base::WeakPtrFactory<ResourceTracker> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ResourceTracker);
};
} // namespace ppapi
#endif // PPAPI_SHARED_IMPL_RESOURCE_TRACKER_H_
|