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

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

Issue 334053008: [SyncFS] Make task invocation in SyncTaskRunner async (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 "base/sequenced_task_runner.h"
10 #include "chrome/browser/sync_file_system/drive_backend/sync_task.h" 11 #include "chrome/browser/sync_file_system/drive_backend/sync_task.h"
11 #include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h" 12 #include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h"
12 #include "chrome/browser/sync_file_system/sync_file_metadata.h" 13 #include "chrome/browser/sync_file_system/sync_file_metadata.h"
13 14
14 using fileapi::FileSystemURL; 15 using fileapi::FileSystemURL;
15 16
16 namespace sync_file_system { 17 namespace sync_file_system {
17 namespace drive_backend { 18 namespace drive_backend {
18 19
19 namespace { 20 namespace {
(...skipping 26 matching lines...) Expand all
46 bool SyncTaskManager::PendingTaskComparator::operator()( 47 bool SyncTaskManager::PendingTaskComparator::operator()(
47 const PendingTask& left, 48 const PendingTask& left,
48 const PendingTask& right) const { 49 const PendingTask& right) const {
49 if (left.priority != right.priority) 50 if (left.priority != right.priority)
50 return left.priority < right.priority; 51 return left.priority < right.priority;
51 return left.seq > right.seq; 52 return left.seq > right.seq;
52 } 53 }
53 54
54 SyncTaskManager::SyncTaskManager( 55 SyncTaskManager::SyncTaskManager(
55 base::WeakPtr<Client> client, 56 base::WeakPtr<Client> client,
56 size_t maximum_background_task) 57 size_t maximum_background_task,
58 base::SequencedTaskRunner* task_runner)
57 : client_(client), 59 : client_(client),
58 maximum_background_task_(maximum_background_task), 60 maximum_background_task_(maximum_background_task),
59 pending_task_seq_(0), 61 pending_task_seq_(0),
60 task_token_seq_(SyncTaskToken::kMinimumBackgroundTaskTokenID) { 62 task_token_seq_(SyncTaskToken::kMinimumBackgroundTaskTokenID),
63 task_runner_(task_runner) {
61 } 64 }
62 65
63 SyncTaskManager::~SyncTaskManager() { 66 SyncTaskManager::~SyncTaskManager() {
64 client_.reset(); 67 client_.reset();
65 token_.reset(); 68 token_.reset();
66 } 69 }
67 70
68 void SyncTaskManager::Initialize(SyncStatusCode status) { 71 void SyncTaskManager::Initialize(SyncStatusCode status) {
69 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 72 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
70 DCHECK(!token_); 73 DCHECK(!token_);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 scoped_ptr<SyncTask> task; 222 scoped_ptr<SyncTask> task;
220 SyncStatusCallback callback = token->callback(); 223 SyncStatusCallback callback = token->callback();
221 token->clear_callback(); 224 token->clear_callback();
222 if (token->token_id() == SyncTaskToken::kForegroundTaskTokenID) { 225 if (token->token_id() == SyncTaskToken::kForegroundTaskTokenID) {
223 token_ = token.Pass(); 226 token_ = token.Pass();
224 task = running_foreground_task_.Pass(); 227 task = running_foreground_task_.Pass();
225 } else { 228 } else {
226 task = running_background_tasks_.take_and_erase(token->token_id()); 229 task = running_background_tasks_.take_and_erase(token->token_id());
227 } 230 }
228 231
232 // Acquire the token to prevent a new task to jump into the queue.
233 token = token_.Pass();
234
229 bool task_used_network = false; 235 bool task_used_network = false;
230 if (task) 236 if (task)
231 task_used_network = task->used_network(); 237 task_used_network = task->used_network();
232 238
233 if (client_) 239 if (client_)
234 client_->NotifyLastOperationStatus(status, task_used_network); 240 client_->NotifyLastOperationStatus(status, task_used_network);
235 241
236 if (!callback.is_null()) 242 if (!callback.is_null())
237 callback.Run(status); 243 callback.Run(status);
238 244
239 StartNextTask(); 245 // Post MaybeStartNextForegroundTask rather than calling it directly to avoid
246 // making the call-chaing longer.
247 task_runner_->PostTask(
248 FROM_HERE,
249 base::Bind(&SyncTaskManager::MaybeStartNextForegroundTask,
250 AsWeakPtr(), base::Passed(&token)));
240 } 251 }
241 252
242 void SyncTaskManager::UpdateBlockingFactorBody( 253 void SyncTaskManager::UpdateBlockingFactorBody(
243 scoped_ptr<SyncTaskToken> foreground_task_token, 254 scoped_ptr<SyncTaskToken> foreground_task_token,
244 scoped_ptr<SyncTaskToken> background_task_token, 255 scoped_ptr<SyncTaskToken> background_task_token,
245 scoped_ptr<TaskLogger::TaskLog> task_log, 256 scoped_ptr<TaskLogger::TaskLog> task_log,
246 scoped_ptr<BlockingFactor> blocking_factor, 257 scoped_ptr<BlockingFactor> blocking_factor,
247 const Continuation& continuation) { 258 const Continuation& continuation) {
248 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 259 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
249 260
(...skipping 22 matching lines...) Expand all
272 if (!foreground_task_token) { 283 if (!foreground_task_token) {
273 PushPendingTask( 284 PushPendingTask(
274 base::Bind(&SyncTaskManager::UpdateBlockingFactorBody, 285 base::Bind(&SyncTaskManager::UpdateBlockingFactorBody,
275 AsWeakPtr(), 286 AsWeakPtr(),
276 base::Passed(&foreground_task_token), 287 base::Passed(&foreground_task_token),
277 base::Passed(&background_task_token), 288 base::Passed(&background_task_token),
278 base::Passed(&task_log), 289 base::Passed(&task_log),
279 base::Passed(&blocking_factor), 290 base::Passed(&blocking_factor),
280 continuation), 291 continuation),
281 PRIORITY_HIGH); 292 PRIORITY_HIGH);
282 StartNextTask(); 293 MaybeStartNextForegroundTask(scoped_ptr<SyncTaskToken>());
283 return; 294 return;
284 } 295 }
285 } 296 }
286 297
287 // Check if the task can run as a background task now. 298 // Check if the task can run as a background task now.
288 // If there are too many task running or any other task blocks current 299 // If there are too many task running or any other task blocks current
289 // task, wait for any other task to finish. 300 // task, wait for any other task to finish.
290 bool task_number_limit_exceeded = 301 bool task_number_limit_exceeded =
291 !background_task_token && 302 !background_task_token &&
292 running_background_tasks_.size() >= maximum_background_task_; 303 running_background_tasks_.size() >= maximum_background_task_;
(...skipping 25 matching lines...) Expand all
318 SyncTaskToken::CreateForBackgroundTask( 329 SyncTaskToken::CreateForBackgroundTask(
319 AsWeakPtr(), 330 AsWeakPtr(),
320 task_token_seq_++, 331 task_token_seq_++,
321 blocking_factor.Pass()); 332 blocking_factor.Pass());
322 background_task_token->UpdateTask(from_here, callback); 333 background_task_token->UpdateTask(from_here, callback);
323 running_background_tasks_.set(background_task_token->token_id(), 334 running_background_tasks_.set(background_task_token->token_id(),
324 running_foreground_task_.Pass()); 335 running_foreground_task_.Pass());
325 } 336 }
326 337
327 token_ = foreground_task_token.Pass(); 338 token_ = foreground_task_token.Pass();
328 StartNextTask(); 339 MaybeStartNextForegroundTask(scoped_ptr<SyncTaskToken>());
329 background_task_token->SetTaskLog(task_log.Pass()); 340 background_task_token->SetTaskLog(task_log.Pass());
330 continuation.Run(background_task_token.Pass()); 341 continuation.Run(background_task_token.Pass());
331 } 342 }
332 343
333 scoped_ptr<SyncTaskToken> SyncTaskManager::GetToken( 344 scoped_ptr<SyncTaskToken> SyncTaskManager::GetToken(
334 const tracked_objects::Location& from_here, 345 const tracked_objects::Location& from_here,
335 const SyncStatusCallback& callback) { 346 const SyncStatusCallback& callback) {
336 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 347 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
337 348
338 if (!token_) 349 if (!token_)
(...skipping 11 matching lines...) Expand all
350 361
351 void SyncTaskManager::RunTask(scoped_ptr<SyncTaskToken> token, 362 void SyncTaskManager::RunTask(scoped_ptr<SyncTaskToken> token,
352 scoped_ptr<SyncTask> task) { 363 scoped_ptr<SyncTask> task) {
353 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 364 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
354 DCHECK(!running_foreground_task_); 365 DCHECK(!running_foreground_task_);
355 366
356 running_foreground_task_ = task.Pass(); 367 running_foreground_task_ = task.Pass();
357 running_foreground_task_->RunPreflight(token.Pass()); 368 running_foreground_task_->RunPreflight(token.Pass());
358 } 369 }
359 370
360 void SyncTaskManager::StartNextTask() { 371 void SyncTaskManager::MaybeStartNextForegroundTask(
372 scoped_ptr<SyncTaskToken> token) {
361 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 373 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
362 374
375 if (token) {
376 DCHECK(!token_);
377 token_ = token.Pass();
378 }
379
363 if (!pending_backgrounding_task_.is_null()) { 380 if (!pending_backgrounding_task_.is_null()) {
364 base::Closure closure = pending_backgrounding_task_; 381 base::Closure closure = pending_backgrounding_task_;
365 pending_backgrounding_task_.Reset(); 382 pending_backgrounding_task_.Reset();
366 closure.Run(); 383 closure.Run();
367 return; 384 return;
368 } 385 }
369 386
387 if (!token_)
388 return;
389
370 if (!pending_tasks_.empty()) { 390 if (!pending_tasks_.empty()) {
371 base::Closure closure = pending_tasks_.top().task; 391 base::Closure closure = pending_tasks_.top().task;
372 pending_tasks_.pop(); 392 pending_tasks_.pop();
373 closure.Run(); 393 closure.Run();
374 return; 394 return;
375 } 395 }
376 396
377 if (client_) 397 if (client_)
378 client_->MaybeScheduleNextTask(); 398 client_->MaybeScheduleNextTask();
379 } 399 }
380 400
381 } // namespace drive_backend 401 } // namespace drive_backend
382 } // namespace sync_file_system 402 } // namespace sync_file_system
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698