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 12namespace ppapi { 13namespace internal { 14 15class ThreadAwareCallbackBase::Core : public base::RefCountedThreadSafe<Core> { 16 public: 17 Core() : aborted_(false) {} 18 19 void MarkAsAborted() { aborted_ = true; } 20 21 void RunIfNotAborted(const base::Closure& closure) { 22 if (!aborted_) 23 CallWhileUnlocked(closure); 24 } 25 26 private: 27 friend class base::RefCountedThreadSafe<Core>; 28 ~Core() {} 29 30 bool aborted_; 31}; 32 33ThreadAwareCallbackBase::ThreadAwareCallbackBase() 34 : target_loop_(PpapiGlobals::Get()->GetCurrentMessageLoop()), 35 core_(new Core()) { 36 DCHECK(target_loop_.get()); 37} 38 39ThreadAwareCallbackBase::~ThreadAwareCallbackBase() { core_->MarkAsAborted(); } 40 41// static 42bool ThreadAwareCallbackBase::HasTargetLoop() { 43 return !!PpapiGlobals::Get()->GetCurrentMessageLoop(); 44} 45 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