thread_aware_callback.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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
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
35ThreadAwareCallbackBase::ThreadAwareCallbackBase()
36    : target_loop_(PpapiGlobals::Get()->GetCurrentMessageLoop()),
37      core_(new Core()) {
38  DCHECK(target_loop_.get());
39}
40
41ThreadAwareCallbackBase::~ThreadAwareCallbackBase() {
42  core_->MarkAsAborted();
43}
44
45// static
46bool ThreadAwareCallbackBase::HasTargetLoop() {
47  return !!PpapiGlobals::Get()->GetCurrentMessageLoop();
48}
49
50void ThreadAwareCallbackBase::InternalRunOnTargetThread(
51    const base::Closure& closure) {
52  if (target_loop_ != 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