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

Side by Side Diff: ppapi/shared_impl/proxy_lock.h

Issue 2666423002: Assert sequence validity on non-thread-safe RefCount manipulations (2) (Closed)
Patch Set: remove DisableSequenceConsistencyAssertions Created 3 years, 8 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
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_SHARED_IMPL_PROXY_LOCK_H_ 5 #ifndef PPAPI_SHARED_IMPL_PROXY_LOCK_H_
6 #define PPAPI_SHARED_IMPL_PROXY_LOCK_H_ 6 #define PPAPI_SHARED_IMPL_PROXY_LOCK_H_
7 7
8 #include <memory> 8 #include <memory>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 // CallWhileLocked and destruction might happen on a different thread from 184 // CallWhileLocked and destruction might happen on a different thread from
185 // creation. 185 // creation.
186 thread_checker_.DetachFromThread(); 186 thread_checker_.DetachFromThread();
187 } 187 }
188 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr) { 188 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr) {
189 // Bind thread_checker_ to this thread so we can check in the destructor. 189 // Bind thread_checker_ to this thread so we can check in the destructor.
190 // *If* the callback gets invoked, it's important that RunWhileLockedHelper 190 // *If* the callback gets invoked, it's important that RunWhileLockedHelper
191 // is destroyed on the same thread (see the comments in the destructor). 191 // is destroyed on the same thread (see the comments in the destructor).
192 DCHECK(ptr->thread_checker_.CalledOnValidThread()); 192 DCHECK(ptr->thread_checker_.CalledOnValidThread());
193 ProxyAutoLock lock; 193 ProxyAutoLock lock;
194
195 // Relax the cross-thread access restriction to non-thread-safe RefCount.
196 // |lock| above protects the access to Resource instances.
197 base::ScopedAllowCrossThreadRefCountAccess
198 allow_cross_thread_ref_count_access;
199
194 { 200 {
195 // Use a scope and local Callback to ensure that the callback is cleared 201 // Use a scope and local Callback to ensure that the callback is cleared
196 // before the lock is released, even in the unlikely event that Run() 202 // before the lock is released, even in the unlikely event that Run()
197 // throws an exception. 203 // throws an exception.
198 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); 204 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_));
199 temp_callback->Run(); 205 temp_callback->Run();
200 } 206 }
201 } 207 }
202 208
203 ~RunWhileLockedHelper() { 209 ~RunWhileLockedHelper() {
(...skipping 11 matching lines...) Expand all
215 // we got pushed to has been destroyed (e.g., the thread is shut down and 221 // we got pushed to has been destroyed (e.g., the thread is shut down and
216 // its MessageLoop destroyed before all tasks have run.) 222 // its MessageLoop destroyed before all tasks have run.)
217 // 223 //
218 // We still need to have the lock when we destroy the callback: 224 // We still need to have the lock when we destroy the callback:
219 // - Because Resource and Var inherit RefCounted (not 225 // - Because Resource and Var inherit RefCounted (not
220 // ThreadSafeRefCounted). 226 // ThreadSafeRefCounted).
221 // - Because if the callback owns the last ref to a Resource, it will 227 // - Because if the callback owns the last ref to a Resource, it will
222 // call the ResourceTracker and also the Resource's destructor, which 228 // call the ResourceTracker and also the Resource's destructor, which
223 // both require the ProxyLock. 229 // both require the ProxyLock.
224 ProxyAutoLock lock; 230 ProxyAutoLock lock;
231
232 // Relax the cross-thread access restriction to non-thread-safe RefCount.
233 // |lock| above protects the access to Resource instances.
234 base::ScopedAllowCrossThreadRefCountAccess
235 allow_cross_thread_ref_count_access;
236
225 callback_.reset(); 237 callback_.reset();
226 } 238 }
227 } 239 }
228 240
229 private: 241 private:
230 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); 242 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper);
231 std::unique_ptr<CallbackType> callback_; 243 std::unique_ptr<CallbackType> callback_;
232 244
233 // Used to ensure that the Callback is run and deleted on the same thread. 245 // Used to ensure that the Callback is run and deleted on the same thread.
234 base::ThreadChecker thread_checker_; 246 base::ThreadChecker thread_checker_;
235 }; 247 };
236 248
237 template <typename P1> 249 template <typename P1>
238 class RunWhileLockedHelper<void(P1)> { 250 class RunWhileLockedHelper<void(P1)> {
239 public: 251 public:
240 typedef base::Callback<void(P1)> CallbackType; 252 typedef base::Callback<void(P1)> CallbackType;
241 explicit RunWhileLockedHelper(const CallbackType& callback) 253 explicit RunWhileLockedHelper(const CallbackType& callback)
242 : callback_(new CallbackType(callback)) { 254 : callback_(new CallbackType(callback)) {
243 thread_checker_.DetachFromThread(); 255 thread_checker_.DetachFromThread();
244 } 256 }
245 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr, 257 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr,
246 P1 p1) { 258 P1 p1) {
247 DCHECK(ptr->thread_checker_.CalledOnValidThread()); 259 DCHECK(ptr->thread_checker_.CalledOnValidThread());
248 ProxyAutoLock lock; 260 ProxyAutoLock lock;
261 // Relax the cross-thread access restriction to non-thread-safe RefCount.
262 // |lock| above protects the access to Resource instances.
263 base::ScopedAllowCrossThreadRefCountAccess
264 allow_cross_thread_ref_count_access;
249 { 265 {
250 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); 266 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_));
251 temp_callback->Run(p1); 267 temp_callback->Run(p1);
252 } 268 }
253 } 269 }
254 ~RunWhileLockedHelper() { 270 ~RunWhileLockedHelper() {
255 DCHECK(thread_checker_.CalledOnValidThread()); 271 DCHECK(thread_checker_.CalledOnValidThread());
256 if (callback_) { 272 if (callback_) {
257 ProxyAutoLock lock; 273 ProxyAutoLock lock;
274 // Relax the cross-thread access restriction to non-thread-safe RefCount.
275 // |lock| above protects the access to Resource instances.
276 base::ScopedAllowCrossThreadRefCountAccess
277 allow_cross_thread_ref_count_access;
258 callback_.reset(); 278 callback_.reset();
259 } 279 }
260 } 280 }
261 281
262 private: 282 private:
263 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); 283 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper);
264 std::unique_ptr<CallbackType> callback_; 284 std::unique_ptr<CallbackType> callback_;
265 base::ThreadChecker thread_checker_; 285 base::ThreadChecker thread_checker_;
266 }; 286 };
267 287
268 template <typename P1, typename P2> 288 template <typename P1, typename P2>
269 class RunWhileLockedHelper<void(P1, P2)> { 289 class RunWhileLockedHelper<void(P1, P2)> {
270 public: 290 public:
271 typedef base::Callback<void(P1, P2)> CallbackType; 291 typedef base::Callback<void(P1, P2)> CallbackType;
272 explicit RunWhileLockedHelper(const CallbackType& callback) 292 explicit RunWhileLockedHelper(const CallbackType& callback)
273 : callback_(new CallbackType(callback)) { 293 : callback_(new CallbackType(callback)) {
274 thread_checker_.DetachFromThread(); 294 thread_checker_.DetachFromThread();
275 } 295 }
276 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr, 296 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr,
277 P1 p1, 297 P1 p1,
278 P2 p2) { 298 P2 p2) {
279 DCHECK(ptr->thread_checker_.CalledOnValidThread()); 299 DCHECK(ptr->thread_checker_.CalledOnValidThread());
280 ProxyAutoLock lock; 300 ProxyAutoLock lock;
301 // Relax the cross-thread access restriction to non-thread-safe RefCount.
302 // |lock| above protects the access to Resource instances.
303 base::ScopedAllowCrossThreadRefCountAccess
304 allow_cross_thread_ref_count_access;
281 { 305 {
282 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); 306 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_));
283 temp_callback->Run(p1, p2); 307 temp_callback->Run(p1, p2);
284 } 308 }
285 } 309 }
286 ~RunWhileLockedHelper() { 310 ~RunWhileLockedHelper() {
287 DCHECK(thread_checker_.CalledOnValidThread()); 311 DCHECK(thread_checker_.CalledOnValidThread());
288 if (callback_) { 312 if (callback_) {
289 ProxyAutoLock lock; 313 ProxyAutoLock lock;
314 // Relax the cross-thread access restriction to non-thread-safe RefCount.
315 // |lock| above protects the access to Resource instances.
316 base::ScopedAllowCrossThreadRefCountAccess
317 allow_cross_thread_ref_count_access;
290 callback_.reset(); 318 callback_.reset();
291 } 319 }
292 } 320 }
293 321
294 private: 322 private:
295 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); 323 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper);
296 std::unique_ptr<CallbackType> callback_; 324 std::unique_ptr<CallbackType> callback_;
297 base::ThreadChecker thread_checker_; 325 base::ThreadChecker thread_checker_;
298 }; 326 };
299 327
300 template <typename P1, typename P2, typename P3> 328 template <typename P1, typename P2, typename P3>
301 class RunWhileLockedHelper<void(P1, P2, P3)> { 329 class RunWhileLockedHelper<void(P1, P2, P3)> {
302 public: 330 public:
303 typedef base::Callback<void(P1, P2, P3)> CallbackType; 331 typedef base::Callback<void(P1, P2, P3)> CallbackType;
304 explicit RunWhileLockedHelper(const CallbackType& callback) 332 explicit RunWhileLockedHelper(const CallbackType& callback)
305 : callback_(new CallbackType(callback)) { 333 : callback_(new CallbackType(callback)) {
306 thread_checker_.DetachFromThread(); 334 thread_checker_.DetachFromThread();
307 } 335 }
308 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr, 336 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr,
309 P1 p1, 337 P1 p1,
310 P2 p2, 338 P2 p2,
311 P3 p3) { 339 P3 p3) {
312 DCHECK(ptr->thread_checker_.CalledOnValidThread()); 340 DCHECK(ptr->thread_checker_.CalledOnValidThread());
313 ProxyAutoLock lock; 341 ProxyAutoLock lock;
342 // Relax the cross-thread access restriction to non-thread-safe RefCount.
343 // |lock| above protects the access to Resource instances.
344 base::ScopedAllowCrossThreadRefCountAccess
345 allow_cross_thread_ref_count_access;
314 { 346 {
315 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); 347 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_));
316 temp_callback->Run(p1, p2, p3); 348 temp_callback->Run(p1, p2, p3);
317 } 349 }
318 } 350 }
319 ~RunWhileLockedHelper() { 351 ~RunWhileLockedHelper() {
320 DCHECK(thread_checker_.CalledOnValidThread()); 352 DCHECK(thread_checker_.CalledOnValidThread());
321 if (callback_) { 353 if (callback_) {
322 ProxyAutoLock lock; 354 ProxyAutoLock lock;
355 // Relax the cross-thread access restriction to non-thread-safe RefCount.
356 // |lock| above protects the access to Resource instances.
357 base::ScopedAllowCrossThreadRefCountAccess
358 allow_cross_thread_ref_count_access;
323 callback_.reset(); 359 callback_.reset();
324 } 360 }
325 } 361 }
326 362
327 private: 363 private:
328 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); 364 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper);
329 std::unique_ptr<CallbackType> callback_; 365 std::unique_ptr<CallbackType> callback_;
330 base::ThreadChecker thread_checker_; 366 base::ThreadChecker thread_checker_;
331 }; 367 };
332 368
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 std::unique_ptr<internal::RunWhileLockedHelper<FunctionType>> helper( 417 std::unique_ptr<internal::RunWhileLockedHelper<FunctionType>> helper(
382 new internal::RunWhileLockedHelper<FunctionType>(callback)); 418 new internal::RunWhileLockedHelper<FunctionType>(callback));
383 return base::Bind( 419 return base::Bind(
384 &internal::RunWhileLockedHelper<FunctionType>::CallWhileLocked, 420 &internal::RunWhileLockedHelper<FunctionType>::CallWhileLocked,
385 base::Passed(std::move(helper))); 421 base::Passed(std::move(helper)));
386 } 422 }
387 423
388 } // namespace ppapi 424 } // namespace ppapi
389 425
390 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_ 426 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/mailbox_manager_sync.cc ('k') | ppapi/shared_impl/tracked_callback.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698