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. 4 5#include "cc/trees/blocking_task_runner.h" 6 7#include <utility> 8 9#include "base/callback.h" 10#include "base/logging.h" 11#include "base/message_loop/message_loop_proxy.h" 12 13namespace cc { 14 15// static 16scoped_ptr<BlockingTaskRunner> BlockingTaskRunner::Create( 17 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { 18 return make_scoped_ptr(new BlockingTaskRunner(task_runner)); 19} 20 21BlockingTaskRunner::BlockingTaskRunner( 22 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 23 : thread_id_(base::PlatformThread::CurrentId()), 24 task_runner_(task_runner), 25 capture_(0) { 26} 27 28BlockingTaskRunner::~BlockingTaskRunner() {} 29 30bool BlockingTaskRunner::BelongsToCurrentThread() { 31 return base::PlatformThread::CurrentId() == thread_id_; 32} 33 34bool BlockingTaskRunner::PostTask(const tracked_objects::Location& from_here, 35 const base::Closure& task) { 36 base::AutoLock lock(lock_); 37 DCHECK(task_runner_.get() || capture_); 38 if (!capture_) 39 return task_runner_->PostTask(from_here, task); 40 captured_tasks_.push_back(task); 41 return true; 42} 43 44void BlockingTaskRunner::SetCapture(bool capture) { 45 DCHECK(BelongsToCurrentThread()); 46 47 std::vector<base::Closure> tasks; 48 49 { 50 base::AutoLock lock(lock_); 51 capture_ += capture ? 1 : -1; 52 DCHECK_GE(capture_, 0); 53 54 if (capture_) 55 return; 56 57 // We're done capturing, so grab all the captured tasks and run them. 58 tasks.swap(captured_tasks_); 59 } 60 for (size_t i = 0; i < tasks.size(); ++i) 61 tasks[i].Run(); 62} 63 64BlockingTaskRunner::CapturePostTasks::CapturePostTasks( 65 BlockingTaskRunner* blocking_runner) 66 : blocking_runner_(blocking_runner) { 67 blocking_runner_->SetCapture(true); 68} 69 70BlockingTaskRunner::CapturePostTasks::~CapturePostTasks() { 71 blocking_runner_->SetCapture(false); 72} 73 74} // namespace cc 75