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

Unified Diff: content/browser/blob_storage/chrome_blob_storage_context.cc

Issue 2055053003: [BlobAsync] Disk support for blob storage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/blob_storage/chrome_blob_storage_context.cc
diff --git a/content/browser/blob_storage/chrome_blob_storage_context.cc b/content/browser/blob_storage/chrome_blob_storage_context.cc
index 533d3f10e222532aaa763dc26afc2df05a448995..aa559ea6c9b87a647c4b255fd4c95ab8f308fd63 100644
--- a/content/browser/blob_storage/chrome_blob_storage_context.cc
+++ b/content/browser/blob_storage/chrome_blob_storage_context.cc
@@ -7,7 +7,14 @@
#include <utility>
#include "base/bind.h"
+#include "base/files/file.h"
+#include "base/files/file_enumerator.h"
+#include "base/files/file_util.h"
#include "base/guid.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/single_thread_task_runner.h"
+#include "base/task_runner.h"
+#include "base/threading/sequenced_worker_pool.h"
#include "content/public/browser/blob_handle.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -15,12 +22,47 @@
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_storage_context.h"
+using base::FilePath;
using base::UserDataAdapter;
using storage::BlobStorageContext;
namespace content {
namespace {
+const char kBlobStorageParentDirectory[] = "blob_storage";
+
+void CreateBlobDirectory(const FilePath& blob_storage_dir,
+ scoped_refptr<base::TaskRunner> io_runner,
+ const base::Closure& done) {
+ base::File::Error error;
+ bool success = base::CreateDirectoryAndGetError(blob_storage_dir, &error);
+ LOCAL_HISTOGRAM_BOOLEAN("Storage.Blob.DirectorySuccess", success);
+ if (!success) {
+ LOCAL_HISTOGRAM_ENUMERATION("Storage.Blob.DirectorySuccess.Error", -error,
+ -base::File::FILE_ERROR_MAX);
+ } else {
+ io_runner->PostTask(FROM_HERE, done);
+ }
+}
+
+// Removes all folders in the parent directory except for the
+// |current_run_dir| folder. If this path is empty, then we delete all folders.
+void RemoveOldBlobStorageDirectories(const FilePath& blob_storage_parent,
+ const FilePath& current_run_dir) {
+ if (!base::DirectoryExists(blob_storage_parent)) {
+ return;
+ }
+ base::FileEnumerator enumerator(blob_storage_parent, false,
+ base::FileEnumerator::DIRECTORIES);
+ std::vector<std::string> components;
+ bool success = true;
+ for (base::FilePath name = enumerator.Next(); !name.empty();
+ name = enumerator.Next()) {
+ if (current_run_dir.empty() || name != current_run_dir)
+ success &= base::DeleteFile(name, true);
+ }
+ LOCAL_HISTOGRAM_BOOLEAN("Storage.Blob.CleanupSuccess", success);
+}
const char kBlobStorageContextKeyName[] = "content_blob_storage_context";
@@ -49,12 +91,46 @@ ChromeBlobStorageContext* ChromeBlobStorageContext::GetFor(
context->SetUserData(
kBlobStorageContextKeyName,
new UserDataAdapter<ChromeBlobStorageContext>(blob.get()));
+
// Check first to avoid memory leak in unittests.
- if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
+ bool io_thread_valid = BrowserThread::IsMessageLoopValid(BrowserThread::IO);
+ if (io_thread_valid) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ChromeBlobStorageContext::InitializeOnIOThread, blob));
}
+
+ // If we're not incognito mode, schedule all of our file tasks to enable
+ // disk on the storage context.
+ if (!context->IsOffTheRecord() && io_thread_valid &&
+ BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) {
Marijn Kruisselbrink 2016/07/12 21:33:06 Does this check still make sense now you're not ac
dmurph 2016/07/14 01:04:30 Done.
+ // Resolve our storage directories.
+ base::FilePath blob_storage_parent =
+ context->GetPath().Append(kBlobStorageParentDirectory);
+ base::FilePath blob_storage_dir =
+ blob_storage_parent.Append(base::GenerateGUID());
+
+ scoped_refptr<base::SingleThreadTaskRunner> io_runner =
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
+ scoped_refptr<base::SequencedWorkerPool> file_pool =
+ BrowserThread::GetBlockingPool();
+
+ // This creates our directory and calls |OnBlobDirectoryCreated| if we're
+ // successful.
+ file_pool->PostWorkerTaskWithShutdownBehavior(
+ FROM_HERE,
+ base::Bind(
+ &CreateBlobDirectory, blob_storage_dir, io_runner,
+ base::Bind(&ChromeBlobStorageContext::OnBlobDirectoryCreated,
+ blob, blob_storage_dir)),
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+
+ // Removes our old blob directories if they exist.
+ file_pool->PostWorkerTaskWithShutdownBehavior(
+ FROM_HERE, base::Bind(&RemoveOldBlobStorageDirectories,
+ blob_storage_parent, blob_storage_dir),
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+ }
}
return UserDataAdapter<ChromeBlobStorageContext>::Get(
@@ -64,6 +140,11 @@ ChromeBlobStorageContext* ChromeBlobStorageContext::GetFor(
void ChromeBlobStorageContext::InitializeOnIOThread() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
context_.reset(new BlobStorageContext());
+ if (!blob_storage_dir_.empty()) {
+ // This happens if we create our blob storage folder before this method is
+ // called, so we enable disk here.
+ context_->EnableDisk(blob_storage_dir_, BrowserThread::GetBlockingPool());
+ }
}
std::unique_ptr<BlobHandle> ChromeBlobStorageContext::CreateMemoryBackedBlob(
@@ -109,6 +190,13 @@ std::unique_ptr<BlobHandle> ChromeBlobStorageContext::CreateFileBackedBlob(
ChromeBlobStorageContext::~ChromeBlobStorageContext() {}
void ChromeBlobStorageContext::DeleteOnCorrectThread() const {
+ // Schedule a task to delete all blob directories.
+ if (!blob_storage_dir_.empty()) {
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
Marijn Kruisselbrink 2016/07/12 21:33:06 Should this also be on the blocking pool rather th
dmurph 2016/07/14 01:04:30 Done.
+ base::Bind(&RemoveOldBlobStorageDirectories,
+ blob_storage_dir_.DirName(), base::FilePath()));
+ }
if (BrowserThread::IsMessageLoopValid(BrowserThread::IO) &&
!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this);
@@ -117,4 +205,15 @@ void ChromeBlobStorageContext::DeleteOnCorrectThread() const {
delete this;
}
+void ChromeBlobStorageContext::OnBlobDirectoryCreated(
+ const base::FilePath& blob_storage_directory) {
+ LOG(ERROR) << "Blob directory successfully created "
+ << blob_storage_directory.value();
+ DCHECK(blob_storage_dir_.empty());
+ blob_storage_dir_ = blob_storage_directory;
+ if (context_) {
+ context_->EnableDisk(blob_storage_dir_, BrowserThread::GetBlockingPool());
+ }
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698