// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ppapi/shared_impl/thread_aware_callback.h" #include "base/callback.h" #include "base/logging.h" #include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/ppb_message_loop_shared.h" namespace ppapi { namespace internal { class ThreadAwareCallbackBase::Core : public base::RefCountedThreadSafe<Core> { public: Core() : aborted_(false) {} void MarkAsAborted() { aborted_ = true; } void RunIfNotAborted(const base::Closure& closure) { if (!aborted_) CallWhileUnlocked(closure); } private: friend class base::RefCountedThreadSafe<Core>; ~Core() {} bool aborted_; }; ThreadAwareCallbackBase::ThreadAwareCallbackBase() : target_loop_(PpapiGlobals::Get()->GetCurrentMessageLoop()), core_(new Core()) { DCHECK(target_loop_.get()); } ThreadAwareCallbackBase::~ThreadAwareCallbackBase() { core_->MarkAsAborted(); } // static bool ThreadAwareCallbackBase::HasTargetLoop() { return !!PpapiGlobals::Get()->GetCurrentMessageLoop(); } void ThreadAwareCallbackBase::InternalRunOnTargetThread( const base::Closure& closure) { if (target_loop_.get() != PpapiGlobals::Get()->GetCurrentMessageLoop()) { target_loop_->PostClosure( FROM_HERE, RunWhileLocked(base::Bind(&Core::RunIfNotAborted, core_, closure)), 0); } else { CallWhileUnlocked(closure); } } } // namespace internal } // namespace ppapi