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"
9 #include "base/logging.h"
11 namespace sync_file_system
{
12 namespace drive_backend
{
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.
36 itr
= items_to_insert
.begin();
37 for (; itr
!= end
; ++itr
)
38 container
->erase(*itr
);
45 bool InsertPaths(std::vector
<base::FilePath
> paths_to_insert
,
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
)) {
52 for (itr
= paths_to_insert
.begin(); itr
!= end
; ++itr
)
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_
)
80 ++running_task_count_
;
84 if (task_blocker
->exclusive
) {
85 if (running_task_count_
||
86 !tracker_ids_
.empty() ||
88 !paths_by_app_id_
.empty())
90 ++running_task_count_
;
91 running_exclusive_task_
= 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_
;
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
:
121 void TaskDependencyManager::Erase(const TaskBlocker
* task_blocker
) {
122 --running_task_count_
;
123 DCHECK_LE(0, running_task_count_
);
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;
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