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: 17 Core() : aborted_(false) { 18 } 19 20 void MarkAsAborted() { aborted_ = true; } 21 22 void RunIfNotAborted(const base::Closure& closure) { 23 if (!aborted_) 24 CallWhileUnlocked(closure); 25 } 26 27 private: 28 friend class base::RefCountedThreadSafe<Core>; 29 ~Core() { 30 } 31 32 bool aborted_; 33 }; 34 35 ThreadAwareCallbackBase::ThreadAwareCallbackBase() 36 : target_loop_(PpapiGlobals::Get()->GetCurrentMessageLoop()), 37 core_(new Core()) { 38 DCHECK(target_loop_.get()); 39 } 40 41 ThreadAwareCallbackBase::~ThreadAwareCallbackBase() { 42 core_->MarkAsAborted(); 43 } 44 45 // static 46 bool ThreadAwareCallbackBase::HasTargetLoop() { 47 return !!PpapiGlobals::Get()->GetCurrentMessageLoop(); 48 } 49 50 void ThreadAwareCallbackBase::InternalRunOnTargetThread( 51 const base::Closure& closure) { 52 if (target_loop_.get() != PpapiGlobals::Get()->GetCurrentMessageLoop()) { 53 target_loop_->PostClosure( 54 FROM_HERE, 55 RunWhileLocked(base::Bind(&Core::RunIfNotAborted, core_, closure)), 56 0); 57 } else { 58 CallWhileUnlocked(closure); 59 } 60 } 61 62 } // namespace internal 63 } // namespace ppapi 64