1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file.
4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/browser/startup_task_runner.h"
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/bind.h"
8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/location.h"
9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/message_loop/message_loop.h"
10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace content {
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)StartupTaskRunner::StartupTaskRunner(
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    base::Callback<void(int)> const startup_complete_callback,
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> proxy)
16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    : startup_complete_callback_(startup_complete_callback), proxy_(proxy) {}
17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)StartupTaskRunner::~StartupTaskRunner() {}
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void StartupTaskRunner::AddTask(StartupTask& callback) {
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  task_list_.push_back(callback);
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StartupTaskRunner::StartRunningTasksAsync() {
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(proxy_.get());
26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int result = 0;
27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (task_list_.empty()) {
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (!startup_complete_callback_.is_null()) {
29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      startup_complete_callback_.Run(result);
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Clear the callback to prevent it being called a second time
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      startup_complete_callback_.Reset();
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  } else {
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const base::Closure next_task =
35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&StartupTaskRunner::WrappedTask, base::Unretained(this));
36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    proxy_->PostNonNestableTask(FROM_HERE, next_task);
37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void StartupTaskRunner::RunAllTasksNow() {
41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int result = 0;
42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  for (std::list<StartupTask>::iterator it = task_list_.begin();
43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)       it != task_list_.end();
44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)       it++) {
45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    result = it->Run();
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (result > 0) break;
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  task_list_.clear();
49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!startup_complete_callback_.is_null()) {
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    startup_complete_callback_.Run(result);
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Clear the callback to prevent it being called a second time
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    startup_complete_callback_.Reset();
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void StartupTaskRunner::WrappedTask() {
57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (task_list_.empty()) {
58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // This will happen if the remaining tasks have been run synchronously since
59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // the WrappedTask was created. Any callback will already have been called,
60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // so there is nothing to do
61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int result = task_list_.front().Run();
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  task_list_.pop_front();
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (result > 0) {
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Stop now and throw away the remaining tasks
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    task_list_.clear();
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (task_list_.empty()) {
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (!startup_complete_callback_.is_null()) {
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      startup_complete_callback_.Run(result);
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Clear the callback to prevent it being called a second time
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      startup_complete_callback_.Reset();
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  } else {
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const base::Closure next_task =
77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        base::Bind(&StartupTaskRunner::WrappedTask, base::Unretained(this));
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    proxy_->PostNonNestableTask(FROM_HERE, next_task);
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace content
83