Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1639)

Side by Side Diff: chrome/browser/chromeos/drive/drive_scheduler.cc

Issue 11142036: Add Move operation to the the scheduler (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Code review fixes Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/drive/drive_scheduler.h" 5 #include "chrome/browser/chromeos/drive/drive_scheduler.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
(...skipping 16 matching lines...) Expand all
27 DriveScheduler::JobInfo::JobInfo(JobType in_job_type, FilePath in_file_path) 27 DriveScheduler::JobInfo::JobInfo(JobType in_job_type, FilePath in_file_path)
28 : job_type(in_job_type), 28 : job_type(in_job_type),
29 job_id(-1), 29 job_id(-1),
30 completed_bytes(0), 30 completed_bytes(0),
31 total_bytes(0), 31 total_bytes(0),
32 file_path(in_file_path), 32 file_path(in_file_path),
33 state(STATE_NONE) { 33 state(STATE_NONE) {
34 } 34 }
35 35
36 DriveScheduler::QueueEntry::QueueEntry(JobType in_job_type, 36 DriveScheduler::QueueEntry::QueueEntry(JobType in_job_type,
37 FilePath in_file_path) 37 FilePath in_file_path,
38 : job_info(TYPE_REMOVE, in_file_path) { 38 FileOperationCallback in_callback)
39 : job_info(in_job_type, in_file_path),
40 callback(in_callback),
41 is_recursive(false) {
39 } 42 }
40 43
41 DriveScheduler::QueueEntry::~QueueEntry() { 44 DriveScheduler::QueueEntry::~QueueEntry() {
42 } 45 }
43 46
44 DriveScheduler::RemoveJobPrivate::RemoveJobPrivate(
45 bool in_is_recursive,
46 FileOperationCallback in_callback)
47 : is_recursive(in_is_recursive),
48 callback(in_callback) {
49 }
50
51 DriveScheduler::RemoveJobPrivate::~RemoveJobPrivate() {
52 }
53
54 DriveScheduler::DriveScheduler(Profile* profile, 47 DriveScheduler::DriveScheduler(Profile* profile,
55 file_system::DriveOperations* drive_operations) 48 file_system::DriveOperations* drive_operations)
56 : job_loop_is_running_(false), 49 : job_loop_is_running_(false),
57 next_job_id_(0), 50 next_job_id_(0),
58 throttle_count_(0), 51 throttle_count_(0),
59 disable_throttling_(false), 52 disable_throttling_(false),
60 drive_operations_(drive_operations), 53 drive_operations_(drive_operations),
61 profile_(profile), 54 profile_(profile),
62 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 55 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
64 } 57 }
65 58
66 DriveScheduler::~DriveScheduler() { 59 DriveScheduler::~DriveScheduler() {
67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
68 61
69 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 62 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
70 } 63 }
71 64
72 void DriveScheduler::Initialize() { 65 void DriveScheduler::Initialize() {
73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
74 67
75 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 68 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
76 } 69 }
77 70
71 void DriveScheduler::Move(const FilePath& src_file_path,
72 const FilePath& dest_file_path,
73 const FileOperationCallback& callback) {
74 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
75
76 scoped_ptr<QueueEntry> new_job(
77 new QueueEntry(TYPE_MOVE, src_file_path, callback));
78 new_job->dest_file_path = dest_file_path;
79
80 QueueJob(new_job.Pass());
81
82 StartJobLoop();
83 }
78 84
79 void DriveScheduler::Remove(const FilePath& file_path, 85 void DriveScheduler::Remove(const FilePath& file_path,
80 bool is_recursive, 86 bool is_recursive,
81 const FileOperationCallback& callback) { 87 const FileOperationCallback& callback) {
82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
83 89
84 QueueEntry* new_job = new QueueEntry(TYPE_REMOVE, file_path); 90 scoped_ptr<QueueEntry> new_job(
85 new_job->remove_private.reset(new RemoveJobPrivate(is_recursive, callback)); 91 new QueueEntry(TYPE_REMOVE, file_path, callback));
92 new_job->is_recursive = is_recursive;
86 93
87 QueueJob(new_job); 94 QueueJob(new_job.Pass());
88 95
89 StartJobLoop(); 96 StartJobLoop();
90 } 97 }
91 98
92 int DriveScheduler::QueueJob(QueueEntry* job) { 99 int DriveScheduler::QueueJob(scoped_ptr<QueueEntry> job) {
93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
94 101
95 int job_id = next_job_id_; 102 int job_id = next_job_id_;
96 job->job_info.job_id = job_id; 103 job->job_info.job_id = job_id;
97 next_job_id_++; 104 next_job_id_++;
98 105
99 queue_.push_back(job_id); 106 queue_.push_back(job_id);
100 107
101 DCHECK(job_info_.find(job_id) == job_info_.end()); 108 DCHECK(job_info_map_.find(job_id) == job_info_map_.end());
102 job_info_[job_id] = make_linked_ptr(job); 109 job_info_map_[job_id] = make_linked_ptr(job.release());
103 110
104 return job_id; 111 return job_id;
105 } 112 }
106 113
107 void DriveScheduler::StartJobLoop() { 114 void DriveScheduler::StartJobLoop() {
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
109 116
110 if (!job_loop_is_running_) 117 if (!job_loop_is_running_)
111 DoJobLoop(); 118 DoJobLoop();
112 } 119 }
113 120
114 void DriveScheduler::DoJobLoop() { 121 void DriveScheduler::DoJobLoop() {
115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
116 123
117 if (queue_.empty() || ShouldStopJobLoop()) { 124 if (queue_.empty() || ShouldStopJobLoop()) {
118 // Note that |queue_| is not cleared so the sync loop can resume. 125 // Note that |queue_| is not cleared so the sync loop can resume.
119 job_loop_is_running_ = false; 126 job_loop_is_running_ = false;
120 return; 127 return;
121 } 128 }
122 job_loop_is_running_ = true; 129 job_loop_is_running_ = true;
123 130
124 // Should copy before calling queue_.pop_front(). 131 // Should copy before calling queue_.pop_front().
125 int job_id = queue_.front(); 132 int job_id = queue_.front();
126 queue_.pop_front(); 133 queue_.pop_front();
127 134
128 JobMap::iterator job_iter = job_info_.find(job_id); 135 JobMap::iterator job_iter = job_info_map_.find(job_id);
129 DCHECK(job_iter != job_info_.end()); 136 DCHECK(job_iter != job_info_map_.end());
130 137
131 JobInfo& job_info = job_iter->second->job_info; 138 JobInfo& job_info = job_iter->second->job_info;
132 job_info.state = STATE_RUNNING; 139 job_info.state = STATE_RUNNING;
133 140
134 switch (job_info.job_type) { 141 switch (job_info.job_type) {
135 case TYPE_REMOVE: { 142 case TYPE_MOVE: {
136 DCHECK(job_iter->second->remove_private.get()); 143 drive_operations_->Move(
137
138 drive_operations_->Remove(
139 job_info.file_path, 144 job_info.file_path,
140 job_iter->second->remove_private->is_recursive, 145 job_iter->second->dest_file_path,
141 base::Bind(&DriveScheduler::OnRemoveDone, 146 base::Bind(&DriveScheduler::OnJobDone,
142 weak_ptr_factory_.GetWeakPtr(), 147 weak_ptr_factory_.GetWeakPtr(),
143 job_id)); 148 job_id));
144 } 149 }
150 break;
151
152 case TYPE_REMOVE: {
153 drive_operations_->Remove(
154 job_info.file_path,
155 job_iter->second->is_recursive,
156 base::Bind(&DriveScheduler::OnJobDone,
157 weak_ptr_factory_.GetWeakPtr(),
158 job_id));
159 }
145 break; 160 break;
146 } 161 }
147 162
148 } 163 }
149 164
150 bool DriveScheduler::ShouldStopJobLoop() { 165 bool DriveScheduler::ShouldStopJobLoop() {
151 // Should stop if the gdata feature was disabled while running the fetch 166 // Should stop if the gdata feature was disabled while running the fetch
152 // loop. 167 // loop.
153 if (profile_->GetPrefs()->GetBoolean(prefs::kDisableGData)) 168 if (profile_->GetPrefs()->GetBoolean(prefs::kDisableGData))
154 return true; 169 return true;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 DCHECK(posted); 205 DCHECK(posted);
191 } 206 }
192 207
193 void DriveScheduler::ResetThrottleAndContinueJobLoop() { 208 void DriveScheduler::ResetThrottleAndContinueJobLoop() {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195 210
196 throttle_count_ = 0; 211 throttle_count_ = 0;
197 DoJobLoop(); 212 DoJobLoop();
198 } 213 }
199 214
200 void DriveScheduler::OnRemoveDone(int job_id, DriveFileError error) { 215 void DriveScheduler::OnJobDone(int job_id, DriveFileError error) {
201 JobMap::iterator job_iter = job_info_.find(job_id); 216 JobMap::iterator job_iter = job_info_map_.find(job_id);
202 DCHECK(job_iter != job_info_.end()); 217 DCHECK(job_iter != job_info_map_.end());
203 218
204 // Retry, depending on the error. 219 // Retry, depending on the error.
205 if (error == DRIVE_FILE_ERROR_THROTTLED || 220 if (error == DRIVE_FILE_ERROR_THROTTLED ||
206 error == DRIVE_FILE_ERROR_NO_CONNECTION) { 221 error == DRIVE_FILE_ERROR_NO_CONNECTION) {
207 job_iter->second->job_info.state = STATE_RETRY; 222 job_iter->second->job_info.state = STATE_RETRY;
208 223
209 // Requeue the job. 224 // Requeue the job.
210 queue_.push_back(job_id); 225 queue_.push_back(job_id);
211 ThrottleAndContinueJobLoop(); 226 ThrottleAndContinueJobLoop();
212 } else { 227 } else {
213 DCHECK(job_iter->second->remove_private.get());
214
215 // Handle the callback. 228 // Handle the callback.
216 if (!job_iter->second->remove_private->callback.is_null()) { 229 if (!job_iter->second->callback.is_null()) {
217 MessageLoop::current()->PostTask(FROM_HERE, 230 MessageLoop::current()->PostTask(FROM_HERE,
218 base::Bind(job_iter->second->remove_private->callback, error)); 231 base::Bind(job_iter->second->callback, error));
219 } 232 }
220 233
221 // Delete the job. 234 // Delete the job.
222 job_info_.erase(job_id); 235 job_info_map_.erase(job_id);
223 ResetThrottleAndContinueJobLoop(); 236 ResetThrottleAndContinueJobLoop();
224 } 237 }
225 } 238 }
226 239
227 void DriveScheduler::OnConnectionTypeChanged( 240 void DriveScheduler::OnConnectionTypeChanged(
228 net::NetworkChangeNotifier::ConnectionType type) { 241 net::NetworkChangeNotifier::ConnectionType type) {
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
230 243
231 // Resume the job loop if the network is back online. Note that we don't 244 // Resume the job loop if the network is back online. Note that we don't
232 // need to check the type of the network as it will be checked in 245 // need to check the type of the network as it will be checked in
233 // ShouldStopJobLoop() as soon as the loop is resumed. 246 // ShouldStopJobLoop() as soon as the loop is resumed.
234 if (!net::NetworkChangeNotifier::IsOffline()) 247 if (!net::NetworkChangeNotifier::IsOffline())
235 StartJobLoop(); 248 StartJobLoop();
236 } 249 }
237 250
238 } // namespace drive 251 } // namespace drive
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698