Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / sync_file_system / drive_backend / task_dependency_manager.cc
blob4d4c4f2bb800bb1be7f8089b086654d0d7c36dd8
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.
5 #include "chrome/browser/sync_file_system/drive_backend/task_dependency_manager.h"
7 #include <utility>
9 #include "base/logging.h"
11 namespace sync_file_system {
12 namespace drive_backend {
14 namespace {
16 // Erases all items in |item_to_erase| from |container|.
17 template <typename Container1, typename Container2>
18 void EraseContainer(const Container1& items_to_erase, Container2* container) {
19 for (typename Container1::const_iterator itr = items_to_erase.begin();
20 itr != items_to_erase.end(); ++itr) {
21 container->erase(*itr);
25 // Inserts all items in |items_to_insert| to |container|, returns true if all
26 // items are inserted successfully. Otherwise, returns false and leave
27 // |container| have the original contents.
28 template <typename Container1, typename Container2>
29 bool InsertAllOrNone(const Container1& items_to_insert, Container2* container) {
30 typedef typename Container1::const_iterator iterator;
31 for (iterator itr = items_to_insert.begin();
32 itr != items_to_insert.end(); ++itr) {
33 if (!container->insert(*itr).second) {
34 // Revert all successful insertion.
35 iterator end = itr;
36 itr = items_to_insert.begin();
37 for (; itr != end; ++itr)
38 container->erase(*itr);
39 return false;
42 return true;
45 bool InsertPaths(std::vector<base::FilePath> paths_to_insert,
46 SubtreeSet* paths) {
47 typedef std::vector<base::FilePath>::const_iterator iterator;
48 for (iterator itr = paths_to_insert.begin();
49 itr != paths_to_insert.end(); ++itr) {
50 if (!paths->insert(*itr)) {
51 iterator end = itr;
52 for (itr = paths_to_insert.begin(); itr != end; ++itr)
53 paths->erase(*itr);
54 return false;
57 return true;
60 } // namespace
62 TaskBlocker::TaskBlocker() : exclusive(false) {}
63 TaskBlocker::~TaskBlocker() {}
65 TaskDependencyManager::TaskDependencyManager()
66 : running_task_count_(0),
67 running_exclusive_task_(false) {}
69 TaskDependencyManager::~TaskDependencyManager() {
70 DCHECK(paths_by_app_id_.empty());
71 DCHECK(file_ids_.empty());
72 DCHECK(tracker_ids_.empty());
75 bool TaskDependencyManager::Insert(const TaskBlocker* task_blocker) {
76 if (running_exclusive_task_)
77 return false;
79 if (!task_blocker) {
80 ++running_task_count_;
81 return true;
84 if (task_blocker->exclusive) {
85 if (running_task_count_ ||
86 !tracker_ids_.empty() ||
87 !file_ids_.empty() ||
88 !paths_by_app_id_.empty())
89 return false;
90 ++running_task_count_;
91 running_exclusive_task_ = true;
92 return true;
95 if (!InsertAllOrNone(task_blocker->tracker_ids, &tracker_ids_))
96 goto fail_on_tracker_id_insertion;
98 if (!InsertAllOrNone(task_blocker->file_ids, &file_ids_))
99 goto fail_on_file_id_insertion;
101 if (!task_blocker->app_id.empty() &&
102 !InsertPaths(task_blocker->paths,
103 &paths_by_app_id_[task_blocker->app_id])) {
104 if (paths_by_app_id_[task_blocker->app_id].empty())
105 paths_by_app_id_.erase(task_blocker->app_id);
106 goto fail_on_path_insertion;
109 ++running_task_count_;
110 return true;
112 fail_on_path_insertion:
113 EraseContainer(task_blocker->file_ids, &file_ids_);
114 fail_on_file_id_insertion:
115 EraseContainer(task_blocker->tracker_ids, &tracker_ids_);
116 fail_on_tracker_id_insertion:
118 return false;
121 void TaskDependencyManager::Erase(const TaskBlocker* task_blocker) {
122 --running_task_count_;
123 DCHECK_LE(0, running_task_count_);
124 if (!task_blocker)
125 return;
127 if (task_blocker->exclusive) {
128 DCHECK(running_exclusive_task_);
129 DCHECK(paths_by_app_id_.empty());
130 DCHECK(file_ids_.empty());
131 DCHECK(tracker_ids_.empty());
132 DCHECK_EQ(0, running_task_count_);
134 running_exclusive_task_ = false;
135 return;
138 if (!task_blocker->app_id.empty()) {
139 EraseContainer(task_blocker->paths,
140 &paths_by_app_id_[task_blocker->app_id]);
141 if (paths_by_app_id_[task_blocker->app_id].empty())
142 paths_by_app_id_.erase(task_blocker->app_id);
145 EraseContainer(task_blocker->file_ids, &file_ids_);
146 EraseContainer(task_blocker->tracker_ids, &tracker_ids_);
149 } // namespace drive_backend
150 } // namespace sync_file_system