| 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 | |
| 200 { | 194 { |
| 201 // Use a scope and local Callback to ensure that the callback is cleared | 195 // Use a scope and local Callback to ensure that the callback is cleared |
| 202 // before the lock is released, even in the unlikely event that Run() | 196 // before the lock is released, even in the unlikely event that Run() |
| 203 // throws an exception. | 197 // throws an exception. |
| 204 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); | 198 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); |
| 205 temp_callback->Run(); | 199 temp_callback->Run(); |
| 206 } | 200 } |
| 207 } | 201 } |
| 208 | 202 |
| 209 ~RunWhileLockedHelper() { | 203 ~RunWhileLockedHelper() { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 221 // we got pushed to has been destroyed (e.g., the thread is shut down and | 215 // we got pushed to has been destroyed (e.g., the thread is shut down and |
| 222 // its MessageLoop destroyed before all tasks have run.) | 216 // its MessageLoop destroyed before all tasks have run.) |
| 223 // | 217 // |
| 224 // We still need to have the lock when we destroy the callback: | 218 // We still need to have the lock when we destroy the callback: |
| 225 // - Because Resource and Var inherit RefCounted (not | 219 // - Because Resource and Var inherit RefCounted (not |
| 226 // ThreadSafeRefCounted). | 220 // ThreadSafeRefCounted). |
| 227 // - Because if the callback owns the last ref to a Resource, it will | 221 // - Because if the callback owns the last ref to a Resource, it will |
| 228 // call the ResourceTracker and also the Resource's destructor, which | 222 // call the ResourceTracker and also the Resource's destructor, which |
| 229 // both require the ProxyLock. | 223 // both require the ProxyLock. |
| 230 ProxyAutoLock lock; | 224 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 | |
| 237 callback_.reset(); | 225 callback_.reset(); |
| 238 } | 226 } |
| 239 } | 227 } |
| 240 | 228 |
| 241 private: | 229 private: |
| 242 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); | 230 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); |
| 243 std::unique_ptr<CallbackType> callback_; | 231 std::unique_ptr<CallbackType> callback_; |
| 244 | 232 |
| 245 // Used to ensure that the Callback is run and deleted on the same thread. | 233 // Used to ensure that the Callback is run and deleted on the same thread. |
| 246 base::ThreadChecker thread_checker_; | 234 base::ThreadChecker thread_checker_; |
| 247 }; | 235 }; |
| 248 | 236 |
| 249 template <typename P1> | 237 template <typename P1> |
| 250 class RunWhileLockedHelper<void(P1)> { | 238 class RunWhileLockedHelper<void(P1)> { |
| 251 public: | 239 public: |
| 252 typedef base::Callback<void(P1)> CallbackType; | 240 typedef base::Callback<void(P1)> CallbackType; |
| 253 explicit RunWhileLockedHelper(const CallbackType& callback) | 241 explicit RunWhileLockedHelper(const CallbackType& callback) |
| 254 : callback_(new CallbackType(callback)) { | 242 : callback_(new CallbackType(callback)) { |
| 255 thread_checker_.DetachFromThread(); | 243 thread_checker_.DetachFromThread(); |
| 256 } | 244 } |
| 257 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr, | 245 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr, |
| 258 P1 p1) { | 246 P1 p1) { |
| 259 DCHECK(ptr->thread_checker_.CalledOnValidThread()); | 247 DCHECK(ptr->thread_checker_.CalledOnValidThread()); |
| 260 ProxyAutoLock lock; | 248 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; | |
| 265 { | 249 { |
| 266 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); | 250 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); |
| 267 temp_callback->Run(p1); | 251 temp_callback->Run(p1); |
| 268 } | 252 } |
| 269 } | 253 } |
| 270 ~RunWhileLockedHelper() { | 254 ~RunWhileLockedHelper() { |
| 271 DCHECK(thread_checker_.CalledOnValidThread()); | 255 DCHECK(thread_checker_.CalledOnValidThread()); |
| 272 if (callback_) { | 256 if (callback_) { |
| 273 ProxyAutoLock lock; | 257 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; | |
| 278 callback_.reset(); | 258 callback_.reset(); |
| 279 } | 259 } |
| 280 } | 260 } |
| 281 | 261 |
| 282 private: | 262 private: |
| 283 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); | 263 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); |
| 284 std::unique_ptr<CallbackType> callback_; | 264 std::unique_ptr<CallbackType> callback_; |
| 285 base::ThreadChecker thread_checker_; | 265 base::ThreadChecker thread_checker_; |
| 286 }; | 266 }; |
| 287 | 267 |
| 288 template <typename P1, typename P2> | 268 template <typename P1, typename P2> |
| 289 class RunWhileLockedHelper<void(P1, P2)> { | 269 class RunWhileLockedHelper<void(P1, P2)> { |
| 290 public: | 270 public: |
| 291 typedef base::Callback<void(P1, P2)> CallbackType; | 271 typedef base::Callback<void(P1, P2)> CallbackType; |
| 292 explicit RunWhileLockedHelper(const CallbackType& callback) | 272 explicit RunWhileLockedHelper(const CallbackType& callback) |
| 293 : callback_(new CallbackType(callback)) { | 273 : callback_(new CallbackType(callback)) { |
| 294 thread_checker_.DetachFromThread(); | 274 thread_checker_.DetachFromThread(); |
| 295 } | 275 } |
| 296 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr, | 276 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr, |
| 297 P1 p1, | 277 P1 p1, |
| 298 P2 p2) { | 278 P2 p2) { |
| 299 DCHECK(ptr->thread_checker_.CalledOnValidThread()); | 279 DCHECK(ptr->thread_checker_.CalledOnValidThread()); |
| 300 ProxyAutoLock lock; | 280 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; | |
| 305 { | 281 { |
| 306 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); | 282 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); |
| 307 temp_callback->Run(p1, p2); | 283 temp_callback->Run(p1, p2); |
| 308 } | 284 } |
| 309 } | 285 } |
| 310 ~RunWhileLockedHelper() { | 286 ~RunWhileLockedHelper() { |
| 311 DCHECK(thread_checker_.CalledOnValidThread()); | 287 DCHECK(thread_checker_.CalledOnValidThread()); |
| 312 if (callback_) { | 288 if (callback_) { |
| 313 ProxyAutoLock lock; | 289 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; | |
| 318 callback_.reset(); | 290 callback_.reset(); |
| 319 } | 291 } |
| 320 } | 292 } |
| 321 | 293 |
| 322 private: | 294 private: |
| 323 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); | 295 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); |
| 324 std::unique_ptr<CallbackType> callback_; | 296 std::unique_ptr<CallbackType> callback_; |
| 325 base::ThreadChecker thread_checker_; | 297 base::ThreadChecker thread_checker_; |
| 326 }; | 298 }; |
| 327 | 299 |
| 328 template <typename P1, typename P2, typename P3> | 300 template <typename P1, typename P2, typename P3> |
| 329 class RunWhileLockedHelper<void(P1, P2, P3)> { | 301 class RunWhileLockedHelper<void(P1, P2, P3)> { |
| 330 public: | 302 public: |
| 331 typedef base::Callback<void(P1, P2, P3)> CallbackType; | 303 typedef base::Callback<void(P1, P2, P3)> CallbackType; |
| 332 explicit RunWhileLockedHelper(const CallbackType& callback) | 304 explicit RunWhileLockedHelper(const CallbackType& callback) |
| 333 : callback_(new CallbackType(callback)) { | 305 : callback_(new CallbackType(callback)) { |
| 334 thread_checker_.DetachFromThread(); | 306 thread_checker_.DetachFromThread(); |
| 335 } | 307 } |
| 336 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr, | 308 static void CallWhileLocked(std::unique_ptr<RunWhileLockedHelper> ptr, |
| 337 P1 p1, | 309 P1 p1, |
| 338 P2 p2, | 310 P2 p2, |
| 339 P3 p3) { | 311 P3 p3) { |
| 340 DCHECK(ptr->thread_checker_.CalledOnValidThread()); | 312 DCHECK(ptr->thread_checker_.CalledOnValidThread()); |
| 341 ProxyAutoLock lock; | 313 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; | |
| 346 { | 314 { |
| 347 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); | 315 std::unique_ptr<CallbackType> temp_callback(std::move(ptr->callback_)); |
| 348 temp_callback->Run(p1, p2, p3); | 316 temp_callback->Run(p1, p2, p3); |
| 349 } | 317 } |
| 350 } | 318 } |
| 351 ~RunWhileLockedHelper() { | 319 ~RunWhileLockedHelper() { |
| 352 DCHECK(thread_checker_.CalledOnValidThread()); | 320 DCHECK(thread_checker_.CalledOnValidThread()); |
| 353 if (callback_) { | 321 if (callback_) { |
| 354 ProxyAutoLock lock; | 322 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; | |
| 359 callback_.reset(); | 323 callback_.reset(); |
| 360 } | 324 } |
| 361 } | 325 } |
| 362 | 326 |
| 363 private: | 327 private: |
| 364 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); | 328 DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper); |
| 365 std::unique_ptr<CallbackType> callback_; | 329 std::unique_ptr<CallbackType> callback_; |
| 366 base::ThreadChecker thread_checker_; | 330 base::ThreadChecker thread_checker_; |
| 367 }; | 331 }; |
| 368 | 332 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 std::unique_ptr<internal::RunWhileLockedHelper<FunctionType>> helper( | 381 std::unique_ptr<internal::RunWhileLockedHelper<FunctionType>> helper( |
| 418 new internal::RunWhileLockedHelper<FunctionType>(callback)); | 382 new internal::RunWhileLockedHelper<FunctionType>(callback)); |
| 419 return base::Bind( | 383 return base::Bind( |
| 420 &internal::RunWhileLockedHelper<FunctionType>::CallWhileLocked, | 384 &internal::RunWhileLockedHelper<FunctionType>::CallWhileLocked, |
| 421 base::Passed(std::move(helper))); | 385 base::Passed(std::move(helper))); |
| 422 } | 386 } |
| 423 | 387 |
| 424 } // namespace ppapi | 388 } // namespace ppapi |
| 425 | 389 |
| 426 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_ | 390 #endif // PPAPI_SHARED_IMPL_PROXY_LOCK_H_ |
| OLD | NEW |