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

Side by Side Diff: ppapi/shared_impl/resource_tracker.cc

Issue 7629017: Add a unified resource tracker shared between the proxy and the impl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Assertion fixed Created 9 years, 4 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
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ppapi/shared_impl/resource_tracker.h"
6
7 #include "ppapi/shared_impl/id_assignment.h"
8 #include "ppapi/shared_impl/resource.h"
9
10 namespace ppapi {
11
12 ResourceTracker::ResourceTracker() : last_resource_value_(0) {
13 }
14
15 ResourceTracker::~ResourceTracker() {
16 }
17
18 Resource* ResourceTracker::GetResource(PP_Resource res) const {
19 ResourceMap::const_iterator i = live_resources_.find(res);
20 if (i == live_resources_.end())
21 return NULL;
22 return i->second.first;
23 }
24
25 bool ResourceTracker::AddRefResource(PP_Resource res) {
26 DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE))
27 << res << " is not a PP_Resource.";
28 ResourceMap::iterator i = live_resources_.find(res);
29 if (i == live_resources_.end())
30 return false;
31
32 // Prevent overflow of refcount.
33 if (i->second.second ==
34 std::numeric_limits<ResourceAndRefCount::second_type>::max())
35 return false;
36
37 // When we go from 0 to 1 plugin ref count, keep an additional "real" ref
38 // on its behalf.
39 if (i->second.second == 0)
40 i->second.first->AddRef();
41
42 i->second.second++;
43 return true;
44 }
45
46 bool ResourceTracker::ReleaseResource(PP_Resource res) {
47 DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE))
48 << res << " is not a PP_Resource.";
49 ResourceMap::iterator i = live_resources_.find(res);
50 if (i == live_resources_.end())
51 return false;
52
53 // Prevent underflow of refcount.
54 if (i->second.second == 0)
55 return false;
56
57 i->second.second--;
58 if (i->second.second == 0) {
59 i->second.first->LastPluginRefWasDeleted();
60
61 // When we go from 0 to 1 plugin ref count, free the additional "real" ref
dmichael (off chromium) 2011/08/17 19:02:54 1 to 0
62 // on its behalf. THIS WILL MOST LIKELY RELEASE THE OBJECT AND REMOVE IT
63 // FROM OUR LIST.
64 i->second.first->Release();
65 }
66 return true;
dmichael (off chromium) 2011/08/17 19:02:54 The return value seems to be true if the resource
67 }
68
69 void ResourceTracker::DidCreateInstance(PP_Instance instance) {
70 // Due to the infrastructure of some tests, the instance is registered
71 // twice in a few cases. It would be nice not to do that and assert here
72 // instead.
73 if (instance_map_.find(instance) != instance_map_.end())
74 return;
75 instance_map_[instance] = linked_ptr<InstanceData>(new InstanceData);
76 }
77
78 void ResourceTracker::DidDeleteInstance(PP_Instance instance) {
79 InstanceMap::iterator found_instance = instance_map_.find(instance);
80
81 // Due to the infrastructure of some tests, the instance is uyregistered
dmichael (off chromium) 2011/08/17 19:02:54 uyregistered->unregistered
82 // twice in a few cases. It would be nice not to do that and assert here
83 // instead.
84 if (found_instance == instance_map_.end())
85 return;
86
87 InstanceData& data = *found_instance->second;
88
89 // Force release all plugin references to resources associated with the
90 // deleted instance. Make a copy since as we iterate through them, each one
91 // will remove itself from the tracking info individually.
92 ResourceSet to_delete = data.resources;
93 ResourceSet::iterator cur = to_delete.begin();
94 while (cur != to_delete.end()) {
95 // Note that it's remotely possible for the object to already be deleted
96 // from the live resources. One case is if a resource object is holding
97 // the last ref to another. When we release the first one, it will release
98 // the second one. So the second one will be gone when we eventually get
99 // to it.
100 ResourceMap::iterator found_resource = live_resources_.find(*cur);
101 if (found_resource != live_resources_.end()) {
102 Resource* resource = found_resource->second.first;
103 if (found_resource->second.second > 0) {
104 resource->LastPluginRefWasDeleted();
105 found_resource->second.second = 0;
106
107 // This will most likely delete the resource object and remove it
108 // from the live_resources_ list.
109 resource->Release();
110 }
111 }
112
113 cur++;
114 }
115
116 // In general the above pass will delete all the resources and there won't
117 // be any left in the map. However, if parts of the implementation are still
118 // holding on to internal refs, we need to tell them that the instance is
119 // gone.
120 to_delete = data.resources;
121 cur = to_delete.begin();
122 while (cur != to_delete.end()) {
123 ResourceMap::iterator found_resource = live_resources_.find(*cur);
124 if (found_resource != live_resources_.end())
125 found_resource->second.first->InstanceWasDeleted();
126 cur++;
127 }
128
129 instance_map_.erase(instance);
130 }
131
132 int ResourceTracker::GetLiveObjectsForInstance(PP_Instance instance) const {
133 InstanceMap::const_iterator found = instance_map_.find(instance);
134 if (found == instance_map_.end())
135 return 0;
136 return static_cast<int>(found->second->resources.size());
137 }
138
139 PP_Resource ResourceTracker::AddResource(Resource* object) {
140 // If the plugin manages to create too many resources, don't do crazy stuff.
dmichael (off chromium) 2011/08/17 19:02:54 Now that we're generating a resource for each inpu
141 if (last_resource_value_ == kMaxPPId)
142 return 0;
143
144 // If you hit this somebody forgot to call DidCreateInstance or the resource
145 // was created with an invalid PP_Instance.
146 DCHECK(instance_map_.find(object->pp_instance()) != instance_map_.end());
147
148 PP_Resource new_id = MakeTypedId(++last_resource_value_, PP_ID_TYPE_RESOURCE);
149 instance_map_[object->pp_instance()]->resources.insert(new_id);
150
151 live_resources_[new_id] = ResourceAndRefCount(object, 0);
152 return new_id;
153 }
154
155 void ResourceTracker::RemoveResource(Resource* object) {
156 PP_Resource pp_resource = object->pp_resource();
157 if (object->pp_instance())
158 instance_map_[object->pp_instance()]->resources.erase(pp_resource);
159 live_resources_.erase(pp_resource);
160 }
161
162
163 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698