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 3 // found in the LICENSE file. 4 5 #include "ppapi/shared_impl/thread_aware_callback.h" 6 7 #include "base/callback.h" 8 #include "base/logging.h" 9 #include "ppapi/shared_impl/ppapi_globals.h" 10 #include "ppapi/shared_impl/ppb_message_loop_shared.h" 11 12 namespace ppapi { 13 namespace internal { 14 15 class ThreadAwareCallbackBase::Core : public base::RefCountedThreadSafe<Core> { 16 public: Core()17 Core() : aborted_(false) {} 18 MarkAsAborted()19 void MarkAsAborted() { aborted_ = true; } 20 RunIfNotAborted(const base::Closure & closure)21 void RunIfNotAborted(const base::Closure& closure) { 22 if (!aborted_) 23 CallWhileUnlocked(closure); 24 } 25 26 private: 27 friend class base::RefCountedThreadSafe<Core>; ~Core()28 ~Core() {} 29 30 bool aborted_; 31 }; 32 ThreadAwareCallbackBase()33ThreadAwareCallbackBase::ThreadAwareCallbackBase() 34 : target_loop_(PpapiGlobals::Get()->GetCurrentMessageLoop()), 35 core_(new Core()) { 36 DCHECK(target_loop_.get()); 37 } 38 ~ThreadAwareCallbackBase()39ThreadAwareCallbackBase::~ThreadAwareCallbackBase() { core_->MarkAsAborted(); } 40 41 // static HasTargetLoop()42bool ThreadAwareCallbackBase::HasTargetLoop() { 43 return !!PpapiGlobals::Get()->GetCurrentMessageLoop(); 44 } 45 InternalRunOnTargetThread(const base::Closure & closure)46void ThreadAwareCallbackBase::InternalRunOnTargetThread( 47 const base::Closure& closure) { 48 if (target_loop_.get() != PpapiGlobals::Get()->GetCurrentMessageLoop()) { 49 target_loop_->PostClosure( 50 FROM_HERE, 51 RunWhileLocked(base::Bind(&Core::RunIfNotAborted, core_, closure)), 52 0); 53 } else { 54 CallWhileUnlocked(closure); 55 } 56 } 57 58 } // namespace internal 59 } // namespace ppapi 60