Provide core API permissions to extensions_unittests
[chromium-blink-merge.git] / cc / trees / blocking_task_runner.cc
blob5c33f40d4fcef5a0c30761b6df26564b41f651a5
1 // Copyright 2013 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.
5 #include "cc/trees/blocking_task_runner.h"
7 #include <utility>
9 #include "base/logging.h"
10 #include "base/memory/singleton.h"
11 #include "base/message_loop/message_loop_proxy.h"
13 namespace cc {
15 struct TaskRunnerPairs {
16 static TaskRunnerPairs* GetInstance() {
17 return Singleton<TaskRunnerPairs>::get();
20 base::Lock lock;
21 std::vector<scoped_refptr<BlockingTaskRunner> > runners;
23 private:
24 friend struct DefaultSingletonTraits<TaskRunnerPairs>;
27 // static
28 scoped_refptr<BlockingTaskRunner> BlockingTaskRunner::current() {
29 TaskRunnerPairs* task_runners = TaskRunnerPairs::GetInstance();
30 base::PlatformThreadId thread_id = base::PlatformThread::CurrentId();
32 base::AutoLock lock(task_runners->lock);
34 scoped_refptr<BlockingTaskRunner> current_task_runner;
36 for (size_t i = 0; i < task_runners->runners.size(); ++i) {
37 if (task_runners->runners[i]->thread_id_ == thread_id) {
38 current_task_runner = task_runners->runners[i];
39 } else if (task_runners->runners[i]->HasOneRef()) {
40 task_runners->runners.erase(task_runners->runners.begin() + i);
41 i--;
45 if (current_task_runner)
46 return current_task_runner;
48 scoped_refptr<BlockingTaskRunner> runner =
49 new BlockingTaskRunner(base::MessageLoopProxy::current());
50 task_runners->runners.push_back(runner);
51 return runner;
54 BlockingTaskRunner::BlockingTaskRunner(
55 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
56 : thread_id_(base::PlatformThread::CurrentId()),
57 task_runner_(task_runner),
58 capture_(0) {
61 BlockingTaskRunner::~BlockingTaskRunner() {}
63 bool BlockingTaskRunner::BelongsToCurrentThread() {
64 return base::PlatformThread::CurrentId() == thread_id_;
67 bool BlockingTaskRunner::PostTask(const tracked_objects::Location& from_here,
68 const base::Closure& task) {
69 base::AutoLock lock(lock_);
70 DCHECK(task_runner_.get() || capture_);
71 if (!capture_)
72 return task_runner_->PostTask(from_here, task);
73 captured_tasks_.push_back(task);
74 return true;
77 void BlockingTaskRunner::SetCapture(bool capture) {
78 DCHECK(BelongsToCurrentThread());
80 std::vector<base::Closure> tasks;
83 base::AutoLock lock(lock_);
84 capture_ += capture ? 1 : -1;
85 DCHECK_GE(capture_, 0);
87 if (capture_)
88 return;
90 // We're done capturing, so grab all the captured tasks and run them.
91 tasks.swap(captured_tasks_);
93 for (size_t i = 0; i < tasks.size(); ++i)
94 tasks[i].Run();
97 BlockingTaskRunner::CapturePostTasks::CapturePostTasks()
98 : blocking_runner_(BlockingTaskRunner::current()) {
99 blocking_runner_->SetCapture(true);
102 BlockingTaskRunner::CapturePostTasks::~CapturePostTasks() {
103 blocking_runner_->SetCapture(false);
106 } // namespace cc