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

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

Issue 10912086: Add CHECKs to ensure that PPAPI resources are created on the right thread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 3 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/shared_impl/resource_tracker.h ('k') | no next file » | 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/shared_impl/resource_tracker.h" 5 #include "ppapi/shared_impl/resource_tracker.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "ppapi/shared_impl/callback_tracker.h" 10 #include "ppapi/shared_impl/callback_tracker.h"
11 #include "ppapi/shared_impl/id_assignment.h" 11 #include "ppapi/shared_impl/id_assignment.h"
12 #include "ppapi/shared_impl/ppapi_globals.h" 12 #include "ppapi/shared_impl/ppapi_globals.h"
13 #include "ppapi/shared_impl/resource.h" 13 #include "ppapi/shared_impl/resource.h"
14 14
15 namespace ppapi { 15 namespace ppapi {
16 16
17 ResourceTracker::ResourceTracker() 17 ResourceTracker::ResourceTracker()
18 : last_resource_value_(0), 18 : last_resource_value_(0),
19 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 19 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
20 } 20 }
21 21
22 ResourceTracker::~ResourceTracker() { 22 ResourceTracker::~ResourceTracker() {
23 } 23 }
24 24
25 Resource* ResourceTracker::GetResource(PP_Resource res) const { 25 Resource* ResourceTracker::GetResource(PP_Resource res) const {
26 CHECK(thread_checker_.CalledOnValidThread());
26 ResourceMap::const_iterator i = live_resources_.find(res); 27 ResourceMap::const_iterator i = live_resources_.find(res);
27 if (i == live_resources_.end()) 28 if (i == live_resources_.end())
28 return NULL; 29 return NULL;
29 return i->second.first; 30 return i->second.first;
30 } 31 }
31 32
32 void ResourceTracker::AddRefResource(PP_Resource res) { 33 void ResourceTracker::AddRefResource(PP_Resource res) {
34 CHECK(thread_checker_.CalledOnValidThread());
33 DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE)) 35 DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE))
34 << res << " is not a PP_Resource."; 36 << res << " is not a PP_Resource.";
35 ResourceMap::iterator i = live_resources_.find(res); 37 ResourceMap::iterator i = live_resources_.find(res);
36 if (i == live_resources_.end()) 38 if (i == live_resources_.end())
37 return; 39 return;
38 40
39 // Prevent overflow of refcount. 41 // Prevent overflow of refcount.
40 if (i->second.second == 42 if (i->second.second ==
41 std::numeric_limits<ResourceAndRefCount::second_type>::max()) 43 std::numeric_limits<ResourceAndRefCount::second_type>::max())
42 return; 44 return;
43 45
44 // When we go from 0 to 1 plugin ref count, keep an additional "real" ref 46 // When we go from 0 to 1 plugin ref count, keep an additional "real" ref
45 // on its behalf. 47 // on its behalf.
46 if (i->second.second == 0) 48 if (i->second.second == 0)
47 i->second.first->AddRef(); 49 i->second.first->AddRef();
48 50
49 i->second.second++; 51 i->second.second++;
50 return; 52 return;
51 } 53 }
52 54
53 void ResourceTracker::ReleaseResource(PP_Resource res) { 55 void ResourceTracker::ReleaseResource(PP_Resource res) {
56 CHECK(thread_checker_.CalledOnValidThread());
54 DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE)) 57 DLOG_IF(ERROR, !CheckIdType(res, PP_ID_TYPE_RESOURCE))
55 << res << " is not a PP_Resource."; 58 << res << " is not a PP_Resource.";
56 ResourceMap::iterator i = live_resources_.find(res); 59 ResourceMap::iterator i = live_resources_.find(res);
57 if (i == live_resources_.end()) 60 if (i == live_resources_.end())
58 return; 61 return;
59 62
60 // Prevent underflow of refcount. 63 // Prevent underflow of refcount.
61 if (i->second.second == 0) 64 if (i->second.second == 0)
62 return; 65 return;
63 66
(...skipping 10 matching lines...) Expand all
74 77
75 void ResourceTracker::ReleaseResourceSoon(PP_Resource res) { 78 void ResourceTracker::ReleaseResourceSoon(PP_Resource res) {
76 MessageLoop::current()->PostNonNestableTask( 79 MessageLoop::current()->PostNonNestableTask(
77 FROM_HERE, 80 FROM_HERE,
78 base::Bind(&ResourceTracker::ReleaseResource, 81 base::Bind(&ResourceTracker::ReleaseResource,
79 weak_ptr_factory_.GetWeakPtr(), 82 weak_ptr_factory_.GetWeakPtr(),
80 res)); 83 res));
81 } 84 }
82 85
83 void ResourceTracker::DidCreateInstance(PP_Instance instance) { 86 void ResourceTracker::DidCreateInstance(PP_Instance instance) {
87 CHECK(thread_checker_.CalledOnValidThread());
84 // Due to the infrastructure of some tests, the instance is registered 88 // Due to the infrastructure of some tests, the instance is registered
85 // twice in a few cases. It would be nice not to do that and assert here 89 // twice in a few cases. It would be nice not to do that and assert here
86 // instead. 90 // instead.
87 if (instance_map_.find(instance) != instance_map_.end()) 91 if (instance_map_.find(instance) != instance_map_.end())
88 return; 92 return;
89 instance_map_[instance] = linked_ptr<InstanceData>(new InstanceData); 93 instance_map_[instance] = linked_ptr<InstanceData>(new InstanceData);
90 } 94 }
91 95
92 void ResourceTracker::DidDeleteInstance(PP_Instance instance) { 96 void ResourceTracker::DidDeleteInstance(PP_Instance instance) {
97 CHECK(thread_checker_.CalledOnValidThread());
93 InstanceMap::iterator found_instance = instance_map_.find(instance); 98 InstanceMap::iterator found_instance = instance_map_.find(instance);
94 99
95 // Due to the infrastructure of some tests, the instance is unregistered 100 // Due to the infrastructure of some tests, the instance is unregistered
96 // twice in a few cases. It would be nice not to do that and assert here 101 // twice in a few cases. It would be nice not to do that and assert here
97 // instead. 102 // instead.
98 if (found_instance == instance_map_.end()) 103 if (found_instance == instance_map_.end())
99 return; 104 return;
100 105
101 InstanceData& data = *found_instance->second; 106 InstanceData& data = *found_instance->second;
102 107
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 ResourceMap::iterator found_resource = live_resources_.find(*cur); 142 ResourceMap::iterator found_resource = live_resources_.find(*cur);
138 if (found_resource != live_resources_.end()) 143 if (found_resource != live_resources_.end())
139 found_resource->second.first->InstanceWasDeleted(); 144 found_resource->second.first->InstanceWasDeleted();
140 cur++; 145 cur++;
141 } 146 }
142 147
143 instance_map_.erase(instance); 148 instance_map_.erase(instance);
144 } 149 }
145 150
146 int ResourceTracker::GetLiveObjectsForInstance(PP_Instance instance) const { 151 int ResourceTracker::GetLiveObjectsForInstance(PP_Instance instance) const {
152 CHECK(thread_checker_.CalledOnValidThread());
147 InstanceMap::const_iterator found = instance_map_.find(instance); 153 InstanceMap::const_iterator found = instance_map_.find(instance);
148 if (found == instance_map_.end()) 154 if (found == instance_map_.end())
149 return 0; 155 return 0;
150 return static_cast<int>(found->second->resources.size()); 156 return static_cast<int>(found->second->resources.size());
151 } 157 }
152 158
153 PP_Resource ResourceTracker::AddResource(Resource* object) { 159 PP_Resource ResourceTracker::AddResource(Resource* object) {
160 CHECK(thread_checker_.CalledOnValidThread());
154 // If the plugin manages to create too many resources, don't do crazy stuff. 161 // If the plugin manages to create too many resources, don't do crazy stuff.
155 if (last_resource_value_ == kMaxPPId) 162 if (last_resource_value_ == kMaxPPId)
156 return 0; 163 return 0;
157 164
158 // Allocate an ID. Note there's a rare error condition below that means we 165 // Allocate an ID. Note there's a rare error condition below that means we
159 // could end up not using |new_id|, but that's harmless. 166 // could end up not using |new_id|, but that's harmless.
160 PP_Resource new_id = MakeTypedId(++last_resource_value_, PP_ID_TYPE_RESOURCE); 167 PP_Resource new_id = MakeTypedId(++last_resource_value_, PP_ID_TYPE_RESOURCE);
161 168
162 // Some objects have a 0 instance, meaning they aren't associated with any 169 // Some objects have a 0 instance, meaning they aren't associated with any
163 // instance, so they won't be in |instance_map_|. This is (as of this writing) 170 // instance, so they won't be in |instance_map_|. This is (as of this writing)
(...skipping 11 matching lines...) Expand all
175 return 0; 182 return 0;
176 } 183 }
177 found->second->resources.insert(new_id); 184 found->second->resources.insert(new_id);
178 } 185 }
179 186
180 live_resources_[new_id] = ResourceAndRefCount(object, 0); 187 live_resources_[new_id] = ResourceAndRefCount(object, 0);
181 return new_id; 188 return new_id;
182 } 189 }
183 190
184 void ResourceTracker::RemoveResource(Resource* object) { 191 void ResourceTracker::RemoveResource(Resource* object) {
192 CHECK(thread_checker_.CalledOnValidThread());
185 PP_Resource pp_resource = object->pp_resource(); 193 PP_Resource pp_resource = object->pp_resource();
186 InstanceMap::iterator found = instance_map_.find(object->pp_instance()); 194 InstanceMap::iterator found = instance_map_.find(object->pp_instance());
187 if (found != instance_map_.end()) 195 if (found != instance_map_.end())
188 found->second->resources.erase(pp_resource); 196 found->second->resources.erase(pp_resource);
189 live_resources_.erase(pp_resource); 197 live_resources_.erase(pp_resource);
190 } 198 }
191 199
192 void ResourceTracker::LastPluginRefWasDeleted(Resource* object) { 200 void ResourceTracker::LastPluginRefWasDeleted(Resource* object) {
193 // Bug http://crbug.com/134611 indicates that sometimes the resource tracker 201 // Bug http://crbug.com/134611 indicates that sometimes the resource tracker
194 // is null here. This should never be the case since if we have a resource in 202 // is null here. This should never be the case since if we have a resource in
(...skipping 10 matching lines...) Expand all
205 CHECK(object->pp_instance() || is_message_loop); 213 CHECK(object->pp_instance() || is_message_loop);
206 CallbackTracker* callback_tracker = 214 CallbackTracker* callback_tracker =
207 PpapiGlobals::Get()->GetCallbackTrackerForInstance(object->pp_instance()); 215 PpapiGlobals::Get()->GetCallbackTrackerForInstance(object->pp_instance());
208 CHECK(callback_tracker || is_message_loop); 216 CHECK(callback_tracker || is_message_loop);
209 if (callback_tracker) 217 if (callback_tracker)
210 callback_tracker->PostAbortForResource(object->pp_resource()); 218 callback_tracker->PostAbortForResource(object->pp_resource());
211 object->LastPluginRefWasDeleted(); 219 object->LastPluginRefWasDeleted();
212 } 220 }
213 221
214 } // namespace ppapi 222 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/shared_impl/resource_tracker.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698