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

Side by Side Diff: chrome/browser/sync_file_system/drive_backend/sync_task_manager.cc

Issue 298003003: [SyncFS] Wire TaskLogger to SyncTaskToken and SyncTaskManager (1/3) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 6 years, 6 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 2014 The Chromium Authors. All rights reserved. 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 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/sync_file_system/drive_backend/sync_task_manager.h" 5 #include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h" 10 #include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h"
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 DCHECK(!manager); 148 DCHECK(!manager);
149 continuation.Run(current_task_token.Pass()); 149 continuation.Run(current_task_token.Pass());
150 return; 150 return;
151 } 151 }
152 152
153 if (!manager) 153 if (!manager)
154 return; 154 return;
155 155
156 scoped_ptr<SyncTaskToken> foreground_task_token; 156 scoped_ptr<SyncTaskToken> foreground_task_token;
157 scoped_ptr<SyncTaskToken> background_task_token; 157 scoped_ptr<SyncTaskToken> background_task_token;
158 scoped_ptr<TaskLogger::TaskLog> task_log = current_task_token->PassTaskLog();
158 if (current_task_token->token_id() == SyncTaskToken::kForegroundTaskTokenID) 159 if (current_task_token->token_id() == SyncTaskToken::kForegroundTaskTokenID)
159 foreground_task_token = current_task_token.Pass(); 160 foreground_task_token = current_task_token.Pass();
160 else 161 else
161 background_task_token = current_task_token.Pass(); 162 background_task_token = current_task_token.Pass();
162 163
163 manager->UpdateBlockingFactorBody(foreground_task_token.Pass(), 164 manager->UpdateBlockingFactorBody(foreground_task_token.Pass(),
164 background_task_token.Pass(), 165 background_task_token.Pass(),
166 task_log.Pass(),
165 blocking_factor.Pass(), 167 blocking_factor.Pass(),
166 continuation); 168 continuation);
167 } 169 }
168 170
169 bool SyncTaskManager::IsRunningTask(int64 token_id) const { 171 bool SyncTaskManager::IsRunningTask(int64 token_id) const {
170 // If the client is gone, all task should be aborted. 172 // If the client is gone, all task should be aborted.
171 if (!client_) 173 if (!client_)
172 return false; 174 return false;
173 175
174 if (token_id == SyncTaskToken::kForegroundTaskTokenID) 176 if (token_id == SyncTaskToken::kForegroundTaskTokenID)
175 return true; 177 return true;
176 178
177 return ContainsKey(running_background_tasks_, token_id); 179 return ContainsKey(running_background_tasks_, token_id);
178 } 180 }
179 181
180 void SyncTaskManager::NotifyTaskDoneBody(scoped_ptr<SyncTaskToken> token, 182 void SyncTaskManager::NotifyTaskDoneBody(scoped_ptr<SyncTaskToken> token,
181 SyncStatusCode status) { 183 SyncStatusCode status) {
182 DCHECK(token); 184 DCHECK(token);
183 185
184 DVLOG(3) << "NotifyTaskDone: " << "finished with status=" << status 186 DVLOG(3) << "NotifyTaskDone: " << "finished with status=" << status
185 << " (" << SyncStatusCodeToString(status) << ")" 187 << " (" << SyncStatusCodeToString(status) << ")"
186 << " " << token_->location().ToString(); 188 << " " << token_->location().ToString();
187 189
188 if (token->blocking_factor()) { 190 if (token->blocking_factor()) {
189 dependency_manager_.Erase(token->blocking_factor()); 191 dependency_manager_.Erase(token->blocking_factor());
190 token->clear_blocking_factor(); 192 token->clear_blocking_factor();
191 } 193 }
192 194
193 // TODO(tzik): Record TaskLog to |client_| here. 195 if (client_)
196 client_->RecordTaskLog(token->PassTaskLog());
194 197
195 scoped_ptr<SyncTask> task; 198 scoped_ptr<SyncTask> task;
196 SyncStatusCallback callback = token->callback(); 199 SyncStatusCallback callback = token->callback();
197 token->clear_callback(); 200 token->clear_callback();
198 if (token->token_id() == SyncTaskToken::kForegroundTaskTokenID) { 201 if (token->token_id() == SyncTaskToken::kForegroundTaskTokenID) {
199 token_ = token.Pass(); 202 token_ = token.Pass();
200 task = running_foreground_task_.Pass(); 203 task = running_foreground_task_.Pass();
201 } else { 204 } else {
202 task = running_background_tasks_.take_and_erase(token->token_id()); 205 task = running_background_tasks_.take_and_erase(token->token_id());
203 } 206 }
204 207
205 bool task_used_network = false; 208 bool task_used_network = false;
206 if (task) 209 if (task)
207 task_used_network = task->used_network(); 210 task_used_network = task->used_network();
208 211
209 if (client_) 212 if (client_)
210 client_->NotifyLastOperationStatus(status, task_used_network); 213 client_->NotifyLastOperationStatus(status, task_used_network);
211 214
212 if (!callback.is_null()) 215 if (!callback.is_null())
213 callback.Run(status); 216 callback.Run(status);
214 217
215 StartNextTask(); 218 StartNextTask();
216 } 219 }
217 220
218 void SyncTaskManager::UpdateBlockingFactorBody( 221 void SyncTaskManager::UpdateBlockingFactorBody(
219 scoped_ptr<SyncTaskToken> foreground_task_token, 222 scoped_ptr<SyncTaskToken> foreground_task_token,
220 scoped_ptr<SyncTaskToken> background_task_token, 223 scoped_ptr<SyncTaskToken> background_task_token,
224 scoped_ptr<TaskLogger::TaskLog> task_log,
221 scoped_ptr<BlockingFactor> blocking_factor, 225 scoped_ptr<BlockingFactor> blocking_factor,
222 const Continuation& continuation) { 226 const Continuation& continuation) {
223 // Run the task directly if the parallelization is disabled. 227 // Run the task directly if the parallelization is disabled.
224 if (!maximum_background_task_) { 228 if (!maximum_background_task_) {
225 DCHECK(foreground_task_token); 229 DCHECK(foreground_task_token);
226 DCHECK(!background_task_token); 230 DCHECK(!background_task_token);
227 continuation.Run(foreground_task_token.Pass()); 231 continuation.Run(foreground_task_token.Pass());
228 return; 232 return;
229 } 233 }
230 234
231 // Clear existing |blocking_factor| from |dependency_manager_| before 235 // Clear existing |blocking_factor| from |dependency_manager_| before
232 // getting |foreground_task_token|, so that we can avoid dead lock. 236 // getting |foreground_task_token|, so that we can avoid dead lock.
233 if (background_task_token && background_task_token->blocking_factor()) { 237 if (background_task_token && background_task_token->blocking_factor()) {
234 dependency_manager_.Erase(background_task_token->blocking_factor()); 238 dependency_manager_.Erase(background_task_token->blocking_factor());
235 background_task_token->clear_blocking_factor(); 239 background_task_token->clear_blocking_factor();
236 } 240 }
237 241
238 // Try to get |foreground_task_token|. If it's not available, wait for 242 // Try to get |foreground_task_token|. If it's not available, wait for
239 // current foreground task to finish. 243 // current foreground task to finish.
240 if (!foreground_task_token) { 244 if (!foreground_task_token) {
241 DCHECK(background_task_token); 245 DCHECK(background_task_token);
242 foreground_task_token = GetToken(background_task_token->location(), 246 foreground_task_token = GetToken(background_task_token->location(),
243 SyncStatusCallback()); 247 SyncStatusCallback());
244 if (!foreground_task_token) { 248 if (!foreground_task_token) {
245 PushPendingTask( 249 PushPendingTask(
246 base::Bind(&SyncTaskManager::UpdateBlockingFactorBody, 250 base::Bind(&SyncTaskManager::UpdateBlockingFactorBody,
247 AsWeakPtr(), 251 AsWeakPtr(),
248 base::Passed(&foreground_task_token), 252 base::Passed(&foreground_task_token),
249 base::Passed(&background_task_token), 253 base::Passed(&background_task_token),
254 base::Passed(&task_log),
250 base::Passed(&blocking_factor), 255 base::Passed(&blocking_factor),
251 continuation), 256 continuation),
252 PRIORITY_HIGH); 257 PRIORITY_HIGH);
253 StartNextTask(); 258 StartNextTask();
254 return; 259 return;
255 } 260 }
256 } 261 }
257 262
258 // Check if the task can run as a background task now. 263 // Check if the task can run as a background task now.
259 // If there are too many task running or any other task blocks current 264 // If there are too many task running or any other task blocks current
260 // task, wait for any other task to finish. 265 // task, wait for any other task to finish.
261 bool task_number_limit_exceeded = 266 bool task_number_limit_exceeded =
262 !background_task_token && 267 !background_task_token &&
263 running_background_tasks_.size() >= maximum_background_task_; 268 running_background_tasks_.size() >= maximum_background_task_;
264 if (task_number_limit_exceeded || 269 if (task_number_limit_exceeded ||
265 !dependency_manager_.Insert(blocking_factor.get())) { 270 !dependency_manager_.Insert(blocking_factor.get())) {
266 DCHECK(!running_background_tasks_.empty()); 271 DCHECK(!running_background_tasks_.empty());
267 DCHECK(pending_backgrounding_task_.is_null()); 272 DCHECK(pending_backgrounding_task_.is_null());
268 273
269 // Wait for NotifyTaskDone to release a |blocking_factor|. 274 // Wait for NotifyTaskDone to release a |blocking_factor|.
270 pending_backgrounding_task_ = 275 pending_backgrounding_task_ =
271 base::Bind(&SyncTaskManager::UpdateBlockingFactorBody, 276 base::Bind(&SyncTaskManager::UpdateBlockingFactorBody,
272 AsWeakPtr(), 277 AsWeakPtr(),
273 base::Passed(&foreground_task_token), 278 base::Passed(&foreground_task_token),
274 base::Passed(&background_task_token), 279 base::Passed(&background_task_token),
280 base::Passed(&task_log),
275 base::Passed(&blocking_factor), 281 base::Passed(&blocking_factor),
276 continuation); 282 continuation);
277 return; 283 return;
278 } 284 }
279 285
280 if (background_task_token) { 286 if (background_task_token) {
281 background_task_token->set_blocking_factor(blocking_factor.Pass()); 287 background_task_token->set_blocking_factor(blocking_factor.Pass());
282 } else { 288 } else {
283 tracked_objects::Location from_here = foreground_task_token->location(); 289 tracked_objects::Location from_here = foreground_task_token->location();
284 SyncStatusCallback callback = foreground_task_token->callback(); 290 SyncStatusCallback callback = foreground_task_token->callback();
285 foreground_task_token->clear_callback(); 291 foreground_task_token->clear_callback();
286 292
287 background_task_token = 293 background_task_token =
288 SyncTaskToken::CreateForBackgroundTask( 294 SyncTaskToken::CreateForBackgroundTask(
289 AsWeakPtr(), 295 AsWeakPtr(),
290 task_token_seq_++, 296 task_token_seq_++,
291 blocking_factor.Pass()); 297 blocking_factor.Pass());
292 background_task_token->UpdateTask(from_here, callback); 298 background_task_token->UpdateTask(from_here, callback);
293 running_background_tasks_.set(background_task_token->token_id(), 299 running_background_tasks_.set(background_task_token->token_id(),
294 running_foreground_task_.Pass()); 300 running_foreground_task_.Pass());
295 } 301 }
296 302
297 token_ = foreground_task_token.Pass(); 303 token_ = foreground_task_token.Pass();
298 StartNextTask(); 304 StartNextTask();
305 background_task_token->SetTaskLog(task_log.Pass());
299 continuation.Run(background_task_token.Pass()); 306 continuation.Run(background_task_token.Pass());
300 } 307 }
301 308
302 scoped_ptr<SyncTaskToken> SyncTaskManager::GetToken( 309 scoped_ptr<SyncTaskToken> SyncTaskManager::GetToken(
303 const tracked_objects::Location& from_here, 310 const tracked_objects::Location& from_here,
304 const SyncStatusCallback& callback) { 311 const SyncStatusCallback& callback) {
305 if (!token_) 312 if (!token_)
306 return scoped_ptr<SyncTaskToken>(); 313 return scoped_ptr<SyncTaskToken>();
307 token_->UpdateTask(from_here, callback); 314 token_->UpdateTask(from_here, callback);
308 return token_.Pass(); 315 return token_.Pass();
309 } 316 }
310 317
311 void SyncTaskManager::PushPendingTask( 318 void SyncTaskManager::PushPendingTask(
312 const base::Closure& closure, Priority priority) { 319 const base::Closure& closure, Priority priority) {
313 pending_tasks_.push(PendingTask(closure, priority, pending_task_seq_++)); 320 pending_tasks_.push(PendingTask(closure, priority, pending_task_seq_++));
314 } 321 }
315 322
316 void SyncTaskManager::RunTask(scoped_ptr<SyncTaskToken> token, 323 void SyncTaskManager::RunTask(scoped_ptr<SyncTaskToken> token,
317 scoped_ptr<SyncTask> task) { 324 scoped_ptr<SyncTask> task) {
318 DCHECK(!running_foreground_task_); 325 DCHECK(!running_foreground_task_);
326
327 token->SetTaskLog(make_scoped_ptr(new TaskLogger::TaskLog));
328
319 running_foreground_task_ = task.Pass(); 329 running_foreground_task_ = task.Pass();
320 running_foreground_task_->RunPreflight(token.Pass()); 330 running_foreground_task_->RunPreflight(token.Pass());
321 } 331 }
322 332
323 void SyncTaskManager::StartNextTask() { 333 void SyncTaskManager::StartNextTask() {
324 if (!pending_backgrounding_task_.is_null()) { 334 if (!pending_backgrounding_task_.is_null()) {
325 base::Closure closure = pending_backgrounding_task_; 335 base::Closure closure = pending_backgrounding_task_;
326 pending_backgrounding_task_.Reset(); 336 pending_backgrounding_task_.Reset();
327 closure.Run(); 337 closure.Run();
328 return; 338 return;
329 } 339 }
330 340
331 if (!pending_tasks_.empty()) { 341 if (!pending_tasks_.empty()) {
332 base::Closure closure = pending_tasks_.top().task; 342 base::Closure closure = pending_tasks_.top().task;
333 pending_tasks_.pop(); 343 pending_tasks_.pop();
334 closure.Run(); 344 closure.Run();
335 return; 345 return;
336 } 346 }
337 347
338 if (client_) 348 if (client_)
339 client_->MaybeScheduleNextTask(); 349 client_->MaybeScheduleNextTask();
340 } 350 }
341 351
342 } // namespace drive_backend 352 } // namespace drive_backend
343 } // namespace sync_file_system 353 } // namespace sync_file_system
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698