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

Unified Diff: content/browser/cache_storage/cache_storage_cache.cc

Issue 2116783002: [CacheStorage] Don't call GetUsageAndQuota from a scheduled operation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2704
Patch Set: Created 4 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/cache_storage/cache_storage_cache.cc
diff --git a/content/browser/cache_storage/cache_storage_cache.cc b/content/browser/cache_storage/cache_storage_cache.cc
index cbe1889d4e69d42b0874f8113200fe07e31149bf..cc3c37ae35f46c6ac69b8ddbf1bfc4d3b812ec6c 100644
--- a/content/browser/cache_storage/cache_storage_cache.cc
+++ b/content/browser/cache_storage/cache_storage_cache.cc
@@ -275,7 +275,6 @@ struct CacheStorageCache::PutContext {
scoped_ptr<storage::BlobDataHandle> blob_data_handle;
CacheStorageCache::ErrorCallback callback;
disk_cache::ScopedEntryPtr cache_entry;
- int64_t available_bytes = 0;
private:
DISALLOW_COPY_AND_ASSIGN(PutContext);
@@ -356,7 +355,51 @@ void CacheStorageCache::BatchOperation(
const std::vector<CacheStorageBatchOperation>& operations,
const ErrorCallback& callback) {
if (!LazyInitialize()) {
- callback.Run(CACHE_STORAGE_ERROR_STORAGE);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, CACHE_STORAGE_ERROR_STORAGE));
+ return;
+ }
+
+ // Estimate the required size of the put operations. The size of the deletes
+ // is unknown and not considered.
+ int64_t space_required = 0;
+ for (const auto& operation : operations) {
+ if (operation.operation_type == CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT) {
+ space_required +=
+ operation.request.blob_size + operation.response.blob_size;
+ }
+ }
+ if (space_required > 0) {
+ // GetUsageAndQuota is called before entering a scheduled operation since it
+ // can call Size, another scheduled operation. This is racy. The decision
+ // to commit is made before the scheduled Put operation runs. By the time
+ // Put runs, the cache might already be full and the origin will be larger
+ // than it's supposed to be.
+ quota_manager_proxy_->GetUsageAndQuota(
+ base::ThreadTaskRunnerHandle::Get().get(), origin_,
+ storage::kStorageTypeTemporary,
+ base::Bind(&CacheStorageCache::BatchDidGetUsageAndQuota,
+ weak_ptr_factory_.GetWeakPtr(), operations, callback,
+ space_required));
+ return;
+ }
+
+ BatchDidGetUsageAndQuota(operations, callback, 0 /* space_required */,
+ storage::kQuotaStatusOk, 0 /* usage */,
+ 0 /* quota */);
+}
+
+void CacheStorageCache::BatchDidGetUsageAndQuota(
+ const std::vector<CacheStorageBatchOperation>& operations,
+ const ErrorCallback& callback,
+ int64_t space_required,
+ storage::QuotaStatusCode status_code,
+ int64_t usage,
+ int64_t quota) {
+ if (status_code != storage::kQuotaStatusOk ||
+ space_required > quota - usage) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, CACHE_STORAGE_ERROR_QUOTA_EXCEEDED));
return;
}
@@ -445,16 +488,13 @@ void CacheStorageCache::Size(const SizeCallback& callback) {
return;
}
- if (initializing_) {
- // Note that Size doesn't use the scheduler, see header comments for why.
- pending_size_callbacks_.push_back(callback);
- return;
- }
+ SizeCallback pending_callback =
+ base::Bind(&CacheStorageCache::PendingSizeCallback,
+ weak_ptr_factory_.GetWeakPtr(), callback);
- // Run immediately so that we don't deadlock on
- // CacheStorageCache::PutDidDelete's call to
- // quota_manager_proxy_->GetUsageAndQuota.
- SizeImpl(callback);
+ scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::SizeImpl,
+ weak_ptr_factory_.GetWeakPtr(),
+ pending_callback));
}
void CacheStorageCache::GetSizeThenClose(const SizeCallback& callback) {
@@ -830,33 +870,8 @@ void CacheStorageCache::PutDidDelete(scoped_ptr<PutContext> put_context,
put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
return;
}
-
- quota_manager_proxy_->GetUsageAndQuota(
- base::ThreadTaskRunnerHandle::Get().get(), origin_,
- storage::kStorageTypeTemporary,
- base::Bind(&CacheStorageCache::PutDidGetUsageAndQuota,
- weak_ptr_factory_.GetWeakPtr(),
- base::Passed(std::move(put_context))));
-}
-
-void CacheStorageCache::PutDidGetUsageAndQuota(
- scoped_ptr<PutContext> put_context,
- storage::QuotaStatusCode status_code,
- int64_t usage,
- int64_t quota) {
- if (backend_state_ != BACKEND_OPEN) {
- put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
- return;
- }
-
- if (status_code != storage::kQuotaStatusOk) {
- put_context->callback.Run(CACHE_STORAGE_ERROR_QUOTA_EXCEEDED);
- return;
- }
-
- put_context->available_bytes = quota - usage;
-
- scoped_ptr<disk_cache::Entry*> scoped_entry_ptr(new disk_cache::Entry*());
+ std::unique_ptr<disk_cache::Entry*> scoped_entry_ptr(
+ new disk_cache::Entry*());
disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
ServiceWorkerFetchRequest* request_ptr = put_context->request.get();
disk_cache::Backend* backend_ptr = backend_.get();
@@ -924,12 +939,6 @@ void CacheStorageCache::PutDidCreateEntry(
scoped_refptr<net::StringIOBuffer> buffer(
new net::StringIOBuffer(std::move(serialized)));
- int64_t bytes_to_write = buffer->size() + put_context->response->blob_size;
- if (put_context->available_bytes < bytes_to_write) {
- put_context->callback.Run(CACHE_STORAGE_ERROR_QUOTA_EXCEEDED);
- return;
- }
-
// Get a temporary copy of the entry pointer before passing it in base::Bind.
disk_cache::Entry* temp_entry_ptr = put_context->cache_entry.get();
@@ -1303,10 +1312,6 @@ void CacheStorageCache::InitGotCacheSize(CacheStorageError cache_create_error,
? BACKEND_OPEN
: BACKEND_CLOSED;
- for (const SizeCallback& callback : pending_size_callbacks_)
- SizeImpl(callback);
- pending_size_callbacks_.clear();
-
UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.InitBackendResult",
cache_create_error, CACHE_STORAGE_ERROR_LAST + 1);
« no previous file with comments | « content/browser/cache_storage/cache_storage_cache.h ('k') | content/browser/cache_storage/cache_storage_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698