12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/recursive_operation_delegate.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage { 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Don't start too many inflight operations. 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMaxInflightOperations = 5; 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)RecursiveOperationDelegate::RecursiveOperationDelegate( 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileSystemContext* file_system_context) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : file_system_context_(file_system_context), 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inflight_operations_(0), 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) canceled_(false) { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)RecursiveOperationDelegate::~RecursiveOperationDelegate() { 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void RecursiveOperationDelegate::Cancel() { 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) canceled_ = true; 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OnCancel(); 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RecursiveOperationDelegate::StartRecursiveOperation( 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& root, 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback) { 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(pending_directory_stack_.empty()); 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(pending_files_.empty()); 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(0, inflight_operations_); 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_ = callback; 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ++inflight_operations_; 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessFile( 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) root, 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&RecursiveOperationDelegate::DidTryProcessFile, 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AsWeakPtr(), root)); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)FileSystemOperationRunner* RecursiveOperationDelegate::operation_runner() { 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return file_system_context_->operation_runner(); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void RecursiveOperationDelegate::OnCancel() { 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void RecursiveOperationDelegate::DidTryProcessFile( 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& root, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(pending_directory_stack_.empty()); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(pending_files_.empty()); 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(1, inflight_operations_); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) --inflight_operations_; 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (canceled_ || error != base::File::FILE_ERROR_NOT_A_FILE) { 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Done(error); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pending_directory_stack_.push(std::queue<FileSystemURL>()); 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pending_directory_stack_.top().push(root); 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessNextDirectory(); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void RecursiveOperationDelegate::ProcessNextDirectory() { 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(pending_files_.empty()); 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!pending_directory_stack_.empty()); 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!pending_directory_stack_.top().empty()); 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(0, inflight_operations_); 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& url = pending_directory_stack_.top().front(); 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ++inflight_operations_; 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessDirectory( 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) url, 84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind( 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &RecursiveOperationDelegate::DidProcessDirectory, AsWeakPtr())); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RecursiveOperationDelegate::DidProcessDirectory( 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(pending_files_.empty()); 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!pending_directory_stack_.empty()); 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!pending_directory_stack_.top().empty()); 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(1, inflight_operations_); 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) --inflight_operations_; 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (canceled_ || error != base::File::FILE_OK) { 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Done(error); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& parent = pending_directory_stack_.top().front(); 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pending_directory_stack_.push(std::queue<FileSystemURL>()); 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) operation_runner()->ReadDirectory( 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) parent, 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&RecursiveOperationDelegate::DidReadDirectory, 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AsWeakPtr(), parent)); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RecursiveOperationDelegate::DidReadDirectory( 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& parent, 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error, 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileEntryList& entries, 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_more) { 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!pending_directory_stack_.empty()); 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(0, inflight_operations_); 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (canceled_ || error != base::File::FILE_OK) { 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Done(error); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < entries.size(); i++) { 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL( 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent.origin(), 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent.mount_type(), 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parent.virtual_path().Append(entries[i].name)); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries[i].is_directory) 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pending_directory_stack_.top().push(url); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_files_.push(url); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Wait for next entries. 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (has_more) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessPendingFiles(); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void RecursiveOperationDelegate::ProcessPendingFiles() { 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!pending_directory_stack_.empty()); 142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if ((pending_files_.empty() || canceled_) && inflight_operations_ == 0) { 144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessSubDirectory(); 145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Do not post any new tasks. 149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (canceled_) 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Run ProcessFile in parallel (upto kMaxInflightOperations). 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> current_message_loop = 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::MessageLoopProxy::current(); 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) while (!pending_files_.empty() && 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inflight_operations_ < kMaxInflightOperations) { 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ++inflight_operations_; 158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) current_message_loop->PostTask( 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FROM_HERE, 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&RecursiveOperationDelegate::ProcessFile, 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AsWeakPtr(), pending_files_.front(), 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&RecursiveOperationDelegate::DidProcessFile, 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AsWeakPtr()))); 164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pending_files_.pop(); 165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void RecursiveOperationDelegate::DidProcessFile( 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) --inflight_operations_; 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If an error occurs, invoke Done immediately (even if there remain 173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // running operations). It is because in the callback, this instance is 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // deleted. 175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Done(error); 176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessPendingFiles(); 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void RecursiveOperationDelegate::ProcessSubDirectory() { 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(pending_files_.empty()); 184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!pending_directory_stack_.empty()); 185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(0, inflight_operations_); 186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (canceled_) { 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Done(base::File::FILE_ERROR_ABORT); 189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!pending_directory_stack_.top().empty()) { 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // There remain some sub directories. Process them first. 194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessNextDirectory(); 195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // All subdirectories are processed. 199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pending_directory_stack_.pop(); 200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (pending_directory_stack_.empty()) { 201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // All files/directories are processed. 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Done(base::File::FILE_OK); 203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!pending_directory_stack_.top().empty()); 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ++inflight_operations_; 208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) PostProcessDirectory( 209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pending_directory_stack_.top().front(), 210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&RecursiveOperationDelegate::DidPostProcessDirectory, 211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AsWeakPtr())); 212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void RecursiveOperationDelegate::DidPostProcessDirectory( 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(pending_files_.empty()); 217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!pending_directory_stack_.empty()); 218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!pending_directory_stack_.top().empty()); 219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(1, inflight_operations_); 220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 221d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) --inflight_operations_; 222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pending_directory_stack_.top().pop(); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (canceled_ || error != base::File::FILE_OK) { 224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Done(error); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessSubDirectory(); 229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RecursiveOperationDelegate::Done(base::File::Error error) { 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (canceled_ && error == base::File::FILE_OK) { 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_ERROR_ABORT); 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback_.Run(error); 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace storage 240