sync_task_manager.h revision effb81e5f8246d0db0270817048dc992db66e9fb
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. 4 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_ 7 8#include <queue> 9#include <vector> 10 11#include "base/callback.h" 12#include "base/containers/scoped_ptr_hash_map.h" 13#include "base/files/file_path.h" 14#include "base/location.h" 15#include "base/memory/scoped_ptr.h" 16#include "base/memory/weak_ptr.h" 17#include "base/threading/non_thread_safe.h" 18#include "chrome/browser/sync_file_system/drive_backend/sync_task.h" 19#include "chrome/browser/sync_file_system/drive_backend/task_dependency_manager.h" 20#include "chrome/browser/sync_file_system/sync_callbacks.h" 21#include "chrome/browser/sync_file_system/sync_status_code.h" 22 23namespace tracked_objects { 24class Location; 25} 26 27namespace sync_file_system { 28namespace drive_backend { 29 30class SyncTaskToken; 31struct BlockingFactor; 32 33class SyncTaskManager 34 : public base::NonThreadSafe, 35 public base::SupportsWeakPtr<SyncTaskManager> { 36 public: 37 typedef base::Callback<void(const SyncStatusCallback& callback)> Task; 38 typedef base::Callback<void(scoped_ptr<SyncTaskToken> token)> Continuation; 39 40 enum Priority { 41 PRIORITY_LOW, 42 PRIORITY_MED, 43 PRIORITY_HIGH, 44 }; 45 46 class Client { 47 public: 48 virtual ~Client() {} 49 50 // Called when the manager is idle. 51 virtual void MaybeScheduleNextTask() = 0; 52 53 // Called when the manager is notified a task is done. 54 virtual void NotifyLastOperationStatus( 55 SyncStatusCode last_operation_status, 56 bool last_operation_used_network) = 0; 57 }; 58 59 // Runs at most |maximum_background_tasks| parallel as background tasks. 60 // If |maximum_background_tasks| is zero, all task runs as foreground task. 61 SyncTaskManager(base::WeakPtr<Client> client, 62 size_t maximum_background_task); 63 virtual ~SyncTaskManager(); 64 65 // This needs to be called to start task scheduling. 66 // If |status| is not SYNC_STATUS_OK calling this may change the 67 // service status. This should not be called more than once. 68 void Initialize(SyncStatusCode status); 69 70 // Schedules a task at the given priority. 71 void ScheduleTask(const tracked_objects::Location& from_here, 72 const Task& task, 73 Priority priority, 74 const SyncStatusCallback& callback); 75 void ScheduleSyncTask(const tracked_objects::Location& from_here, 76 scoped_ptr<SyncTask> task, 77 Priority priority, 78 const SyncStatusCallback& callback); 79 80 // Runs the posted task only when we're idle. Returns true if tha task is 81 // scheduled. 82 bool ScheduleTaskIfIdle(const tracked_objects::Location& from_here, 83 const Task& task, 84 const SyncStatusCallback& callback); 85 bool ScheduleSyncTaskIfIdle(const tracked_objects::Location& from_here, 86 scoped_ptr<SyncTask> task, 87 const SyncStatusCallback& callback); 88 89 static void NotifyTaskDone(scoped_ptr<SyncTaskToken> token, 90 SyncStatusCode status); 91 static void MoveTaskToBackground(scoped_ptr<SyncTaskToken> token, 92 scoped_ptr<BlockingFactor> blocking_factor, 93 const Continuation& continuation); 94 95 bool IsRunningTask(int64 task_token_id) const; 96 97 private: 98 struct PendingTask { 99 base::Closure task; 100 Priority priority; 101 int64 seq; 102 103 PendingTask(); 104 PendingTask(const base::Closure& task, Priority pri, int seq); 105 ~PendingTask(); 106 }; 107 108 struct PendingTaskComparator { 109 bool operator()(const PendingTask& left, 110 const PendingTask& right) const; 111 }; 112 113 // Non-static version of NotifyTaskDone. 114 void NotifyTaskDoneBody(scoped_ptr<SyncTaskToken> token, 115 SyncStatusCode status); 116 117 // Notifies SyncTaskManager that the running task turned to a background task. 118 void NotifyTaskBackgrounded(scoped_ptr<SyncTaskToken> foreground_task_token, 119 const SyncTaskToken& background_task_token); 120 121 // Non-static version of MoveTaskToBackground. 122 void MoveTaskToBackgroundBody(scoped_ptr<SyncTaskToken> token, 123 scoped_ptr<BlockingFactor> blocking_factor, 124 const Continuation& continuation); 125 126 // Returns true if no running background task blocks |blocking_factor|. 127 bool CanRunAsBackgroundTask(const BlockingFactor& blocking_factor); 128 129 // This should be called when an async task needs to get a task token. 130 scoped_ptr<SyncTaskToken> GetToken(const tracked_objects::Location& from_here, 131 const SyncStatusCallback& callback); 132 133 scoped_ptr<SyncTaskToken> GetTokenForBackgroundTask( 134 const tracked_objects::Location& from_here, 135 const SyncStatusCallback& callback, 136 scoped_ptr<BlockingFactor> blocking_factor); 137 138 void PushPendingTask(const base::Closure& closure, Priority priority); 139 140 void RunTask(scoped_ptr<SyncTaskToken> token, 141 scoped_ptr<SyncTask> task); 142 143 void StartNextTask(); 144 145 base::WeakPtr<Client> client_; 146 147 // Owns running SyncTask to cancel the task on SyncTaskManager deletion. 148 scoped_ptr<SyncTask> running_task_; 149 150 // Owns running backgrounded SyncTask to cancel the task on SyncTaskManager 151 // deletion. 152 base::ScopedPtrHashMap<int64, SyncTask> running_background_task_; 153 154 size_t maximum_background_task_; 155 156 // Holds pending continuation to move task to background. 157 base::Closure pending_backgrounding_task_; 158 159 std::priority_queue<PendingTask, std::vector<PendingTask>, 160 PendingTaskComparator> pending_tasks_; 161 int64 pending_task_seq_; 162 int64 task_token_seq_; 163 164 // Absence of |token_| implies a task is running. Incoming tasks should 165 // wait for the task to finish in |pending_tasks_| if |token_| is null. 166 // Each task must take TaskToken instance from |token_| and must hold it 167 // until it finished. And the task must return the instance through 168 // NotifyTaskDone when the task finished. 169 scoped_ptr<SyncTaskToken> token_; 170 171 TaskDependencyManager dependency_manager_; 172 173 DISALLOW_COPY_AND_ASSIGN(SyncTaskManager); 174}; 175 176} // namespace drive_backend 177} // namespace sync_file_system 178 179#endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_SYNC_TASK_MANAGER_H_ 180