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 / sync_task_manager.h
blob6be0e7bcac594461e63c43d269c3bf80b42b6d8a
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 #ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_SYNC_TASK_MANAGER_H_
6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_SYNC_TASK_MANAGER_H_
8 #include <queue>
9 #include <vector>
11 #include "base/callback.h"
12 #include "base/containers/scoped_ptr_hash_map.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/sequence_checker.h"
16 #include "base/threading/sequenced_worker_pool.h"
17 #include "chrome/browser/sync_file_system/drive_backend/task_dependency_manager.h"
18 #include "chrome/browser/sync_file_system/sync_callbacks.h"
19 #include "chrome/browser/sync_file_system/sync_status_code.h"
20 #include "chrome/browser/sync_file_system/task_logger.h"
22 namespace base {
23 class SequencedTaskRunner;
26 namespace tracked_objects {
27 class Location;
30 namespace sync_file_system {
31 namespace drive_backend {
33 class SyncTask;
34 class SyncTaskToken;
35 struct TaskBlocker;
37 // This class manages asynchronous tasks for Sync FileSystem. Each task must be
38 // either a Task or a SyncTask.
39 // The instance runs single task as the foreground task, and multiple tasks as
40 // background tasks. Running background task has a TaskBlocker that
41 // describes which task can run in parallel. When a task start running as a
42 // background task, SyncTaskManager checks if any running background task
43 // doesn't block the new background task, and queues it up if it can't run.
44 class SyncTaskManager {
45 public:
46 typedef base::Callback<void(const SyncStatusCallback& callback)> Task;
47 typedef base::Callback<void(scoped_ptr<SyncTaskToken> token)> Continuation;
49 enum Priority {
50 PRIORITY_LOW,
51 PRIORITY_MED,
52 PRIORITY_HIGH,
55 class Client {
56 public:
57 virtual ~Client() {}
59 // Called when the manager is idle.
60 virtual void MaybeScheduleNextTask() = 0;
62 // Called when the manager is notified a task is done.
63 virtual void NotifyLastOperationStatus(
64 SyncStatusCode last_operation_status,
65 bool last_operation_used_network) = 0;
67 virtual void RecordTaskLog(scoped_ptr<TaskLogger::TaskLog> task_log) = 0;
70 // Runs at most |maximum_background_tasks| parallel as background tasks.
71 // If |maximum_background_tasks| is zero, all task runs as foreground task.
72 SyncTaskManager(base::WeakPtr<Client> client,
73 size_t maximum_background_task,
74 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
75 const scoped_refptr<base::SequencedWorkerPool>& worker_pool);
76 virtual ~SyncTaskManager();
78 // This needs to be called to start task scheduling.
79 // If |status| is not SYNC_STATUS_OK calling this may change the
80 // service status. This should not be called more than once.
81 void Initialize(SyncStatusCode status);
83 // Schedules a task at the given priority.
84 void ScheduleTask(const tracked_objects::Location& from_here,
85 const Task& task,
86 Priority priority,
87 const SyncStatusCallback& callback);
88 void ScheduleSyncTask(const tracked_objects::Location& from_here,
89 scoped_ptr<SyncTask> task,
90 Priority priority,
91 const SyncStatusCallback& callback);
93 // Runs the posted task only when we're idle. Returns true if tha task is
94 // scheduled.
95 bool ScheduleTaskIfIdle(const tracked_objects::Location& from_here,
96 const Task& task,
97 const SyncStatusCallback& callback);
98 bool ScheduleSyncTaskIfIdle(const tracked_objects::Location& from_here,
99 scoped_ptr<SyncTask> task,
100 const SyncStatusCallback& callback);
102 // Notifies SyncTaskManager that the task associated to |token| has finished
103 // with |status|.
104 static void NotifyTaskDone(scoped_ptr<SyncTaskToken> token,
105 SyncStatusCode status);
107 // Updates |task_blocker| associated to the current task by specified
108 // |task_blocker| and turns the current task to a background task if
109 // the current task is running as a foreground task.
110 // If specified |task_blocker| is blocked by any other blocking factor
111 // associated to an existing background task, this function waits for the
112 // existing background task to finish.
113 // Upon the task is ready to run as a background task, calls |continuation|
114 // with new SyncTaskToken.
115 // Note that this function once releases previous |task_blocker| before
116 // applying new |task_blocker|. So, any other task may be run before
117 // invocation of |continuation|.
118 static void UpdateTaskBlocker(scoped_ptr<SyncTaskToken> current_task_token,
119 scoped_ptr<TaskBlocker> task_blocker,
120 const Continuation& continuation);
122 bool IsRunningTask(int64 task_token_id) const;
124 void DetachFromSequence();
125 bool ShouldTrackTaskToken() const;
127 private:
128 struct PendingTask {
129 base::Closure task;
130 Priority priority;
131 int64 seq;
133 PendingTask();
134 PendingTask(const base::Closure& task, Priority pri, int seq);
135 ~PendingTask();
138 struct PendingTaskComparator {
139 bool operator()(const PendingTask& left,
140 const PendingTask& right) const;
143 // Non-static version of NotifyTaskDone.
144 void NotifyTaskDoneBody(scoped_ptr<SyncTaskToken> token,
145 SyncStatusCode status);
147 // Non-static version of UpdateTaskBlocker.
148 void UpdateTaskBlockerBody(scoped_ptr<SyncTaskToken> foreground_task_token,
149 scoped_ptr<SyncTaskToken> background_task_token,
150 scoped_ptr<TaskLogger::TaskLog> task_log,
151 scoped_ptr<TaskBlocker> task_blocker,
152 const Continuation& continuation);
154 // This should be called when an async task needs to get a task token.
155 scoped_ptr<SyncTaskToken> GetToken(const tracked_objects::Location& from_here,
156 const SyncStatusCallback& callback);
158 scoped_ptr<SyncTaskToken> GetTokenForBackgroundTask(
159 const tracked_objects::Location& from_here,
160 const SyncStatusCallback& callback,
161 scoped_ptr<TaskBlocker> task_blocker);
163 void PushPendingTask(const base::Closure& closure, Priority priority);
165 void RunTask(scoped_ptr<SyncTaskToken> token,
166 scoped_ptr<SyncTask> task);
168 // Runs a pending task as a foreground task if possible.
169 // If |token| is non-nullptr, put |token| back to |token_| beforehand.
170 void MaybeStartNextForegroundTask(scoped_ptr<SyncTaskToken> token);
172 base::WeakPtr<Client> client_;
174 // Owns running SyncTask to cancel the task on SyncTaskManager deletion.
175 scoped_ptr<SyncTask> running_foreground_task_;
177 // Owns running backgrounded SyncTask to cancel the task on SyncTaskManager
178 // deletion.
179 base::ScopedPtrHashMap<int64, scoped_ptr<SyncTask>> running_background_tasks_;
181 size_t maximum_background_task_;
183 // Holds pending continuation to move task to background.
184 base::Closure pending_backgrounding_task_;
186 std::priority_queue<PendingTask, std::vector<PendingTask>,
187 PendingTaskComparator> pending_tasks_;
188 int64 pending_task_seq_;
189 int64 task_token_seq_;
191 // Absence of |token_| implies a task is running. Incoming tasks should
192 // wait for the task to finish in |pending_tasks_| if |token_| is null.
193 // Each task must take TaskToken instance from |token_| and must hold it
194 // until it finished. And the task must return the instance through
195 // NotifyTaskDone when the task finished.
196 scoped_ptr<SyncTaskToken> token_;
198 TaskDependencyManager dependency_manager_;
200 scoped_refptr<base::SequencedTaskRunner> task_runner_;
201 scoped_refptr<base::SequencedWorkerPool> worker_pool_;
202 base::SequenceChecker sequence_checker_;
204 base::WeakPtrFactory<SyncTaskManager> weak_ptr_factory_;;
206 DISALLOW_COPY_AND_ASSIGN(SyncTaskManager);
209 } // namespace drive_backend
210 } // namespace sync_file_system
212 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_SYNC_TASK_MANAGER_H_