Home | History | Annotate | Download | only in test
      1 // Copyright 2014 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 "media/cast/test/fake_single_thread_task_runner.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/time/tick_clock.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 namespace media {
     12 namespace cast {
     13 namespace test {
     14 
     15 FakeSingleThreadTaskRunner::FakeSingleThreadTaskRunner(
     16     base::SimpleTestTickClock* clock)
     17     : clock_(clock),
     18       fail_on_next_task_(false) {}
     19 
     20 FakeSingleThreadTaskRunner::~FakeSingleThreadTaskRunner() {}
     21 
     22 bool FakeSingleThreadTaskRunner::PostDelayedTask(
     23     const tracked_objects::Location& from_here,
     24     const base::Closure& task,
     25     base::TimeDelta delay) {
     26   if (fail_on_next_task_) {
     27     LOG(FATAL) << "Infinite task-add loop detected.";
     28   }
     29   CHECK(delay >= base::TimeDelta());
     30   EXPECT_GE(delay, base::TimeDelta());
     31   PostedTask posed_task(from_here,
     32                         task,
     33                         clock_->NowTicks(),
     34                         delay,
     35                         base::TestPendingTask::NESTABLE);
     36 
     37   tasks_.insert(std::make_pair(posed_task.GetTimeToRun(), posed_task));
     38   return false;
     39 }
     40 
     41 bool FakeSingleThreadTaskRunner::RunsTasksOnCurrentThread() const {
     42   return true;
     43 }
     44 
     45 void FakeSingleThreadTaskRunner::RunTasks() {
     46   while (true) {
     47     // Run all tasks equal or older than current time.
     48     std::multimap<base::TimeTicks, PostedTask>::iterator it = tasks_.begin();
     49     if (it == tasks_.end())
     50       return;  // No more tasks.
     51 
     52     PostedTask task = it->second;
     53     if (clock_->NowTicks() < task.GetTimeToRun())
     54       return;
     55 
     56     tasks_.erase(it);
     57     task.task.Run();
     58   }
     59 }
     60 
     61 void FakeSingleThreadTaskRunner::Sleep(base::TimeDelta t) {
     62   base::TimeTicks run_until = clock_->NowTicks() + t;
     63   while (1) {
     64     // If we run more than 100000 iterations, we've probably
     65     // hit some sort of case where a new task is posted every
     66     // time that we invoke a task, and we can't make progress
     67     // anymore. If that happens, set fail_on_next_task_ to true
     68     // and throw an error when the next task is posted.
     69     for (int i = 0; i < 100000; i++) {
     70       // Run all tasks equal or older than current time.
     71       std::multimap<base::TimeTicks, PostedTask>::iterator it = tasks_.begin();
     72       if (it == tasks_.end()) {
     73         clock_->Advance(run_until - clock_->NowTicks());
     74         return;
     75       }
     76 
     77       PostedTask task = it->second;
     78       if (run_until < task.GetTimeToRun()) {
     79         clock_->Advance(run_until - clock_->NowTicks());
     80         return;
     81       }
     82 
     83       clock_->Advance(task.GetTimeToRun() - clock_->NowTicks());
     84       tasks_.erase(it);
     85       task.task.Run();
     86     }
     87     // Instead of failing immediately, we fail when the next task is
     88     // added so that the backtrace will include the task that was added.
     89     fail_on_next_task_ = true;
     90   }
     91 }
     92 
     93 bool FakeSingleThreadTaskRunner::PostNonNestableDelayedTask(
     94     const tracked_objects::Location& from_here,
     95     const base::Closure& task,
     96     base::TimeDelta delay) {
     97   NOTIMPLEMENTED();
     98   return false;
     99 }
    100 
    101 }  // namespace test
    102 }  // namespace cast
    103 }  // namespace media
    104