|  | // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "storage/browser/blob/scoped_file.h" | 
|  |  | 
|  | #include "base/bind.h" | 
|  | #include "base/callback.h" | 
|  | #include "base/files/file_util.h" | 
|  | #include "base/location.h" | 
|  | #include "base/task_runner.h" | 
|  | #include "base/threading/thread_task_runner_handle.h" | 
|  |  | 
|  | namespace storage { | 
|  |  | 
|  | ScopedFile::ScopedFile() | 
|  | : scope_out_policy_(DONT_DELETE_ON_SCOPE_OUT) { | 
|  | } | 
|  |  | 
|  | ScopedFile::ScopedFile(const base::FilePath& path, | 
|  | ScopeOutPolicy policy, | 
|  | const scoped_refptr<base::TaskRunner>& file_task_runner) | 
|  | : path_(path), | 
|  | scope_out_policy_(policy), | 
|  | file_task_runner_(file_task_runner) { | 
|  | DCHECK(path.empty() || policy != DELETE_ON_SCOPE_OUT || | 
|  | file_task_runner.get()) | 
|  | << "path:" << path.value() << " policy:" << policy | 
|  | << " runner:" << file_task_runner.get(); | 
|  | } | 
|  |  | 
|  | ScopedFile::ScopedFile(ScopedFile&& other) { | 
|  | MoveFrom(other); | 
|  | } | 
|  |  | 
|  | ScopedFile::~ScopedFile() { | 
|  | Reset(); | 
|  | } | 
|  |  | 
|  | void ScopedFile::AddScopeOutCallback( | 
|  | const ScopeOutCallback& callback, | 
|  | base::TaskRunner* callback_runner) { | 
|  | if (!callback_runner) | 
|  | callback_runner = base::ThreadTaskRunnerHandle::Get().get(); | 
|  | scope_out_callbacks_.push_back(std::make_pair(callback, callback_runner)); | 
|  | } | 
|  |  | 
|  | base::FilePath ScopedFile::Release() { | 
|  | base::FilePath path = path_; | 
|  | path_.clear(); | 
|  | scope_out_callbacks_.clear(); | 
|  | scope_out_policy_ = DONT_DELETE_ON_SCOPE_OUT; | 
|  | return path; | 
|  | } | 
|  |  | 
|  | void ScopedFile::Reset() { | 
|  | if (path_.empty()) | 
|  | return; | 
|  |  | 
|  | for (ScopeOutCallbackList::iterator iter = scope_out_callbacks_.begin(); | 
|  | iter != scope_out_callbacks_.end(); ++iter) { | 
|  | iter->second->PostTask(FROM_HERE, base::Bind(iter->first, path_)); | 
|  | } | 
|  |  | 
|  | DVLOG(1) << "ScopedFile::Reset(): " | 
|  | << (scope_out_policy_ == DELETE_ON_SCOPE_OUT ? "Deleting " | 
|  | : "Not deleting ") | 
|  | << path_.value(); | 
|  |  | 
|  | if (scope_out_policy_ == DELETE_ON_SCOPE_OUT) { | 
|  | file_task_runner_->PostTask( | 
|  | FROM_HERE, | 
|  | base::Bind(base::IgnoreResult(&base::DeleteFile), | 
|  | path_, false /* recursive */)); | 
|  | } | 
|  |  | 
|  | // Clear all fields. | 
|  | Release(); | 
|  | } | 
|  |  | 
|  | void ScopedFile::MoveFrom(ScopedFile& other) { | 
|  | Reset(); | 
|  |  | 
|  | scope_out_policy_ = other.scope_out_policy_; | 
|  | scope_out_callbacks_.swap(other.scope_out_callbacks_); | 
|  | file_task_runner_ = other.file_task_runner_; | 
|  | path_ = other.Release(); | 
|  | } | 
|  |  | 
|  | }  // namespace storage |