| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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_ |
| OLD | NEW |