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 "content/browser/startup_task_runner.h"
6
7#include "base/bind.h"
8#include "base/location.h"
9#include "base/message_loop/message_loop.h"
10
11namespace content {
12
13StartupTaskRunner::StartupTaskRunner(
14    base::Callback<void(int)> const startup_complete_callback,
15    scoped_refptr<base::SingleThreadTaskRunner> proxy)
16    : startup_complete_callback_(startup_complete_callback), proxy_(proxy) {}
17
18StartupTaskRunner::~StartupTaskRunner() {}
19
20void StartupTaskRunner::AddTask(StartupTask& callback) {
21  task_list_.push_back(callback);
22}
23
24void StartupTaskRunner::StartRunningTasksAsync() {
25  DCHECK(proxy_);
26  int result = 0;
27  if (task_list_.empty()) {
28    if (!startup_complete_callback_.is_null()) {
29      startup_complete_callback_.Run(result);
30      // Clear the callback to prevent it being called a second time
31      startup_complete_callback_.Reset();
32    }
33  } else {
34    const base::Closure next_task =
35        base::Bind(&StartupTaskRunner::WrappedTask, base::Unretained(this));
36    proxy_->PostNonNestableTask(FROM_HERE, next_task);
37  }
38}
39
40void StartupTaskRunner::RunAllTasksNow() {
41  int result = 0;
42  for (std::list<StartupTask>::iterator it = task_list_.begin();
43       it != task_list_.end();
44       it++) {
45    result = it->Run();
46    if (result > 0) break;
47  }
48  task_list_.clear();
49  if (!startup_complete_callback_.is_null()) {
50    startup_complete_callback_.Run(result);
51    // Clear the callback to prevent it being called a second time
52    startup_complete_callback_.Reset();
53  }
54}
55
56void StartupTaskRunner::WrappedTask() {
57  if (task_list_.empty()) {
58    // This will happen if the remaining tasks have been run synchronously since
59    // the WrappedTask was created. Any callback will already have been called,
60    // so there is nothing to do
61    return;
62  }
63  int result = task_list_.front().Run();
64  task_list_.pop_front();
65  if (result > 0) {
66    // Stop now and throw away the remaining tasks
67    task_list_.clear();
68  }
69  if (task_list_.empty()) {
70    if (!startup_complete_callback_.is_null()) {
71      startup_complete_callback_.Run(result);
72      // Clear the callback to prevent it being called a second time
73      startup_complete_callback_.Reset();
74    }
75  } else {
76    const base::Closure next_task =
77        base::Bind(&StartupTaskRunner::WrappedTask, base::Unretained(this));
78    proxy_->PostNonNestableTask(FROM_HERE, next_task);
79  }
80}
81
82}  // namespace content
83