| Index: base/test/sequenced_task_runner_test_template.cc
|
| ===================================================================
|
| --- base/test/sequenced_task_runner_test_template.cc (revision 0)
|
| +++ base/test/sequenced_task_runner_test_template.cc (revision 0)
|
| @@ -0,0 +1,238 @@
|
| +// 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 "base/test/sequenced_task_runner_test_template.h"
|
| +
|
| +namespace base {
|
| +
|
| +namespace internal {
|
| +
|
| +SequencedTaskTracker::TaskStatus::TaskStatus()
|
| + : lock_(),
|
| + start_event_(true, false),
|
| + claimed_(false),
|
| + started_(false),
|
| + completed_(false),
|
| + prev_started_(false),
|
| + prev_completed_(false) {
|
| +}
|
| +
|
| +SequencedTaskTracker::TaskStatus::TaskStatus(const TaskStatus& ts)
|
| + : lock_(),
|
| + start_event_(true, false),
|
| + claimed_(ts.claimed_),
|
| + started_(ts.started_),
|
| + completed_(ts.completed_),
|
| + prev_started_(ts.prev_started_),
|
| + prev_completed_(ts.prev_completed_) {
|
| +}
|
| +
|
| +SequencedTaskTracker::TaskStatus& SequencedTaskTracker::TaskStatus::operator=(
|
| + const TaskStatus& ts) {
|
| + if (&ts == this)
|
| + return *this;
|
| + claimed_ = ts.claimed_;
|
| + started_ = ts.started_;
|
| + completed_ = ts.completed_;
|
| + prev_started_ = ts.prev_started_;
|
| + prev_completed_ = ts.prev_completed_;
|
| + return *this;
|
| +}
|
| +
|
| +bool SequencedTaskTracker::TaskStatus::Claim() {
|
| + AutoLock lock(lock_);
|
| + if (claimed_)
|
| + return false;
|
| + claimed_ = true;
|
| + return true;
|
| +}
|
| +
|
| +bool SequencedTaskTracker::TaskStatus::Started() const {
|
| + start_event_.Wait();
|
| + AutoLock lock(lock_);
|
| + return started_;
|
| +}
|
| +
|
| +bool SequencedTaskTracker::TaskStatus::Completed() const {
|
| + AutoLock lock(lock_);
|
| + return completed_;
|
| +}
|
| +
|
| +// Only called after the run has completed, so locking is not required.
|
| +bool SequencedTaskTracker::TaskStatus::PrevStartedBefore() const {
|
| + return prev_started_;
|
| +}
|
| +
|
| +// Only called after the run has completed, so locking is not required.
|
| +bool SequencedTaskTracker::TaskStatus::PrevCompletedBefore() const {
|
| + return prev_completed_;
|
| +}
|
| +
|
| +void SequencedTaskTracker::TaskStatus::SetStarted() {
|
| + AutoLock lock(lock_);
|
| + started_ = true;
|
| + start_event_.Signal();
|
| +}
|
| +
|
| +void SequencedTaskTracker::TaskStatus::SetCompleted() {
|
| + AutoLock lock(lock_);
|
| + completed_ = true;
|
| +}
|
| +
|
| +void SequencedTaskTracker::TaskStatus::SetPrevStartedBefore(bool b) {
|
| + AutoLock lock(lock_);
|
| + prev_started_ = b;
|
| +}
|
| +
|
| +void SequencedTaskTracker::TaskStatus::SetPrevCompletedBefore(bool b) {
|
| + AutoLock lock(lock_);
|
| + prev_completed_ = b;
|
| +}
|
| +
|
| +bool SequencedTaskTracker::TaskStatus::operator==(const TaskStatus& ts) const {
|
| + return (Completed() == ts.Completed() &&
|
| + started_ == ts.started_ &&
|
| + started_ == ts.started_ &&
|
| + PrevStartedBefore() == ts.PrevStartedBefore() &&
|
| + PrevCompletedBefore() == ts.PrevCompletedBefore());
|
| +}
|
| +
|
| +std::ostream& operator<<(std::ostream& os,
|
| + const SequencedTaskTracker::TaskStatus& ts) {
|
| + return os << "{ started=" << std::boolalpha << ts.started_
|
| + << "; completed=" << ts.Completed()
|
| + << "; prev_started_before=" << ts.PrevStartedBefore()
|
| + << "; prev_completed_before=" << ts.PrevCompletedBefore()
|
| + << " }";
|
| +}
|
| +
|
| +SequencedTaskTracker::SequencedTaskTracker() {
|
| +}
|
| +
|
| +SequencedTaskTracker::~SequencedTaskTracker() {
|
| +}
|
| +
|
| +void SequencedTaskTracker::SetNonNestableTaskCount(
|
| + std::size_t task_count) {
|
| + non_nestable_statuses_.resize(task_count);
|
| +}
|
| +
|
| +void SequencedTaskTracker::SetNestableTaskCount(
|
| + std::size_t task_count) {
|
| + nestable_statuses_.resize(task_count);
|
| +}
|
| +
|
| +void SequencedTaskTracker::FastNonNestableTask(int base_status_i) {
|
| + const int i = ClaimNonNestableTaskStatus(base_status_i);
|
| + non_nestable_statuses_[i].SetStarted();
|
| + // "Started before" is covered by "completed before" for non-nestable tasks.
|
| + non_nestable_statuses_[i].SetPrevStartedBefore(true);
|
| + non_nestable_statuses_[i].SetPrevCompletedBefore(
|
| + i > 0 ? non_nestable_statuses_[i - 1].Completed() : true);
|
| + non_nestable_statuses_[i].SetCompleted();
|
| +}
|
| +
|
| +void SequencedTaskTracker::FastNestableTask(int base_status_i) {
|
| + const int i = ClaimNestableTaskStatus(base_status_i);
|
| + nestable_statuses_[i].SetStarted();
|
| + nestable_statuses_[i].SetPrevStartedBefore(
|
| + i > 0 ? nestable_statuses_[i - 1].Started() : true);
|
| + // Don't care about "completed before" for nestable tasks.
|
| + nestable_statuses_[i].SetPrevCompletedBefore(true);
|
| + nestable_statuses_[i].SetCompleted();
|
| +}
|
| +
|
| +void SequencedTaskTracker::SlowNonNestableTask(int base_status_i) {
|
| + const int i = ClaimNonNestableTaskStatus(base_status_i);
|
| + non_nestable_statuses_[i].SetStarted();
|
| + non_nestable_statuses_[i].SetPrevStartedBefore(true);
|
| + non_nestable_statuses_[i].SetPrevCompletedBefore(
|
| + i > 0 ? non_nestable_statuses_[i - 1].Completed() : true);
|
| + base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
|
| + non_nestable_statuses_[i].SetCompleted();
|
| +}
|
| +
|
| +void SequencedTaskTracker::SlowNestableTask(int base_status_i) {
|
| + const int i = ClaimNestableTaskStatus(base_status_i);
|
| + nestable_statuses_[i].SetStarted();
|
| + nestable_statuses_[i].SetPrevStartedBefore(
|
| + i > 0 ? nestable_statuses_[i - 1].Started() : true);
|
| + // Don't care about "completed before" for nestable tasks.
|
| + nestable_statuses_[i].SetPrevCompletedBefore(true);
|
| + base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
|
| + nestable_statuses_[i].SetCompleted();
|
| +}
|
| +
|
| +void SequencedTaskTracker::PostFastNonNestableFromSlowNonNestable(
|
| + scoped_refptr<SequencedTaskRunner> task_runner,
|
| + const int base_status_i,
|
| + const int child_count) {
|
| +
|
| + const int i = ClaimNonNestableTaskStatus(base_status_i);
|
| + non_nestable_statuses_[i].SetStarted();
|
| +
|
| + non_nestable_statuses_[i].SetPrevStartedBefore(true);
|
| + non_nestable_statuses_[i].SetPrevCompletedBefore(
|
| + i > 0 ? non_nestable_statuses_[i - 1].Completed() : true);
|
| +
|
| + for (int j = 0; j < child_count; ++j) {
|
| + Closure task = Bind(&SequencedTaskTracker::FastNonNestableTask, this, i);
|
| + task_runner->PostNonNestableTask(FROM_HERE, task);
|
| + }
|
| + non_nestable_statuses_[i].SetCompleted();
|
| +}
|
| +
|
| +void SequencedTaskTracker::PostFastNestableFromSlowNonNestable(
|
| + scoped_refptr<SequencedTaskRunner> task_runner,
|
| + const int base_status_i,
|
| + const int child_count) {
|
| + const int i = ClaimNonNestableTaskStatus(base_status_i);
|
| + non_nestable_statuses_[i].SetStarted();
|
| + non_nestable_statuses_[i].SetPrevStartedBefore(true);
|
| + non_nestable_statuses_[i].SetPrevCompletedBefore(
|
| + i > 0 ? non_nestable_statuses_[i - 1].Completed() : true);
|
| +
|
| + for (int j = 0; j < child_count; ++j) {
|
| + const int child_i = i * child_count + j;
|
| + Closure task = Bind(&SequencedTaskTracker::FastNestableTask,
|
| + this,
|
| + child_i);
|
| + task_runner->PostTask(FROM_HERE, task);
|
| + }
|
| + non_nestable_statuses_[i].SetCompleted();
|
| +}
|
| +
|
| +int SequencedTaskTracker::ClaimNonNestableTaskStatus(const int search_from) {
|
| + const int end = static_cast<int>(non_nestable_statuses_.size());
|
| + for (int i = search_from; i < end; ++i) {
|
| + if (non_nestable_statuses_[i].Claim())
|
| + return i;
|
| + }
|
| + CHECK(false) << "Unable to find an unclaimed non-nestable task status slot";
|
| + return -1;
|
| +}
|
| +
|
| +int SequencedTaskTracker::ClaimNestableTaskStatus(const int search_from) {
|
| + const int end = static_cast<int>(nestable_statuses_.size());
|
| + for (int i = search_from; i < end; ++i) {
|
| + if (nestable_statuses_[i].Claim())
|
| + return i;
|
| + }
|
| + CHECK(false) << "Unable to find an unclaimed nestable task status slot";
|
| + return -1;
|
| +}
|
| +
|
| +const SequencedTaskTracker::TaskStatuses&
|
| +SequencedTaskTracker::GetNonNestableTaskStatuses() const {
|
| + return non_nestable_statuses_;
|
| +}
|
| +
|
| +const SequencedTaskTracker::TaskStatuses&
|
| +SequencedTaskTracker::GetNestableTaskStatuses() const {
|
| + return nestable_statuses_;
|
| +}
|
| +
|
| +} // namespace internal
|
| +
|
| +} // namespace base
|
|
|
| Property changes on: base/test/sequenced_task_runner_test_template.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|