Chromium Code Reviews| 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 b7c92d757a44f1b7f2cf2359e953912b342589f3..1e307d5a1ef70ab913a1d2a4cfdcfd335df76f1a 100644 |
| --- a/content/browser/cache_storage/cache_storage_cache.cc |
| +++ b/content/browser/cache_storage/cache_storage_cache.cc |
| @@ -31,8 +31,22 @@ namespace content { |
| namespace { |
| -typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> |
| - EntryBoolCallback; |
| +// This class ensures that the cache and the entry have a lifetime as long as |
| +// the blob that is created to contain them. |
| +class CacheStorageCacheDataHandle |
| + : public storage::BlobDataBuilder::DataHandle { |
| + public: |
| + CacheStorageCacheDataHandle(const scoped_refptr<CacheStorageCache>& cache, |
| + disk_cache::ScopedEntryPtr entry) |
| + : cache_(cache), entry_(entry.Pass()) {} |
| + |
| + private: |
| + ~CacheStorageCacheDataHandle() override {} |
| + |
| + scoped_refptr<CacheStorageCache> cache_; |
| + disk_cache::ScopedEntryPtr entry_; |
|
jkarlin
2015/06/12 15:53:37
DISALLOW_COPY_AND_ASSIGN?
gavinp
2015/06/12 18:10:30
Done.
|
| +}; |
| + |
| typedef base::Callback<void(scoped_ptr<CacheMetadata>)> MetadataCallback; |
| enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; |
| @@ -308,32 +322,12 @@ struct CacheStorageCache::KeysContext { |
| struct CacheStorageCache::MatchContext { |
|
jkarlin
2015/06/12 15:53:37
Might as well remove MatchContext at this point.
gavinp
2015/06/12 18:10:30
Done.
|
| MatchContext(scoped_ptr<ServiceWorkerFetchRequest> request, |
| - const CacheStorageCache::ResponseCallback& callback, |
| - base::WeakPtr<storage::BlobStorageContext> blob_storage_context) |
| - : request(request.Pass()), |
| - original_callback(callback), |
| - blob_storage_context(blob_storage_context), |
| - entry(nullptr), |
| - total_bytes_read(0) {} |
| - |
| - ~MatchContext() { |
| - if (entry) |
| - entry->Close(); |
| - } |
| + const CacheStorageCache::ResponseCallback& callback) |
| + : request(request.Pass()), original_callback(callback) {} |
| - // Input |
| scoped_ptr<ServiceWorkerFetchRequest> request; |
| CacheStorageCache::ResponseCallback original_callback; |
| - base::WeakPtr<storage::BlobStorageContext> blob_storage_context; |
| - disk_cache::Entry* entry; |
| - |
| - // Output |
| - scoped_ptr<ServiceWorkerResponse> response; |
| - scoped_ptr<storage::BlobDataBuilder> blob_data; |
| - |
| - // For reading the cache entry data into a blob. |
| - scoped_refptr<net::IOBufferWithSize> response_body_buffer; |
| - size_t total_bytes_read; |
| + disk_cache::ScopedEntryPtr entry; |
| DISALLOW_COPY_AND_ASSIGN(MatchContext); |
| }; |
| @@ -354,12 +348,7 @@ struct CacheStorageCache::PutContext { |
| blob_data_handle(blob_data_handle.Pass()), |
| callback(callback), |
| request_context_getter(request_context_getter), |
| - quota_manager_proxy(quota_manager_proxy), |
| - cache_entry(NULL) {} |
| - ~PutContext() { |
| - if (cache_entry) |
| - cache_entry->Close(); |
| - } |
| + quota_manager_proxy(quota_manager_proxy) {} |
| // Input parameters to the Put function. |
| GURL origin; |
| @@ -369,10 +358,7 @@ struct CacheStorageCache::PutContext { |
| CacheStorageCache::ErrorCallback callback; |
| scoped_refptr<net::URLRequestContextGetter> request_context_getter; |
| scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy; |
| - |
| - // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to |
| - // CreateEntry. |
| - disk_cache::Entry* cache_entry; |
| + disk_cache::ScopedEntryPtr cache_entry; |
| DISALLOW_COPY_AND_ASSIGN(PutContext); |
| }; |
| @@ -585,13 +571,15 @@ void CacheStorageCache::MatchImpl(scoped_ptr<ServiceWorkerFetchRequest> request, |
| } |
| scoped_ptr<MatchContext> match_context( |
| - new MatchContext(request.Pass(), callback, blob_storage_context_)); |
| + new MatchContext(request.Pass(), callback)); |
| - disk_cache::Entry** entry_ptr = &match_context->entry; |
| + scoped_ptr<disk_cache::Entry*> scoped_entry_ptr(new disk_cache::Entry*()); |
| + disk_cache::Entry** entry_ptr = scoped_entry_ptr.get(); |
| ServiceWorkerFetchRequest* request_ptr = match_context->request.get(); |
| net::CompletionCallback open_entry_callback = base::Bind( |
| &CacheStorageCache::MatchDidOpenEntry, weak_ptr_factory_.GetWeakPtr(), |
| + base::Passed(scoped_entry_ptr.Pass()), |
| base::Passed(match_context.Pass())); |
| int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr, |
| @@ -601,6 +589,7 @@ void CacheStorageCache::MatchImpl(scoped_ptr<ServiceWorkerFetchRequest> request, |
| } |
| void CacheStorageCache::MatchDidOpenEntry( |
| + scoped_ptr<disk_cache::Entry*> entry_ptr, |
| scoped_ptr<MatchContext> match_context, |
| int rv) { |
| if (rv != net::OK) { |
| @@ -610,15 +599,12 @@ void CacheStorageCache::MatchDidOpenEntry( |
| return; |
| } |
| - // Copy the entry pointer before passing it in base::Bind. |
| - disk_cache::Entry* tmp_entry_ptr = match_context->entry; |
| - DCHECK(tmp_entry_ptr); |
| - |
| + match_context->entry.reset(*entry_ptr); |
| MetadataCallback headers_callback = base::Bind( |
| &CacheStorageCache::MatchDidReadMetadata, weak_ptr_factory_.GetWeakPtr(), |
| base::Passed(match_context.Pass())); |
| - ReadMetadata(tmp_entry_ptr, headers_callback); |
| + ReadMetadata(*entry_ptr, headers_callback); |
| } |
| void CacheStorageCache::MatchDidReadMetadata( |
| @@ -631,14 +617,12 @@ void CacheStorageCache::MatchDidReadMetadata( |
| return; |
| } |
| - match_context->response.reset(new ServiceWorkerResponse( |
| + scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse( |
| match_context->request->url, metadata->response().status_code(), |
| metadata->response().status_text(), |
| ProtoResponseTypeToWebResponseType(metadata->response().response_type()), |
| ServiceWorkerHeaderMap(), "", 0, GURL())); |
| - ServiceWorkerResponse* response = match_context->response.get(); |
| - |
| if (metadata->response().has_url()) |
| response->url = GURL(metadata->response().url()); |
| @@ -666,97 +650,32 @@ void CacheStorageCache::MatchDidReadMetadata( |
| } |
| if (match_context->entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) { |
| - match_context->original_callback.Run(CACHE_STORAGE_OK, |
| - match_context->response.Pass(), |
| + match_context->original_callback.Run(CACHE_STORAGE_OK, response.Pass(), |
| scoped_ptr<storage::BlobDataHandle>()); |
| return; |
| } |
| - // Stream the response body into a blob. |
| - if (!match_context->blob_storage_context) { |
| + if (!blob_storage_context_) { |
| match_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE, |
| scoped_ptr<ServiceWorkerResponse>(), |
| scoped_ptr<storage::BlobDataHandle>()); |
| return; |
| } |
| + // Create a blob with the response body data. |
| + response->blob_size = match_context->entry->GetDataSize(INDEX_RESPONSE_BODY); |
| response->blob_uuid = base::GenerateGUID(); |
| - |
| - match_context->blob_data.reset( |
| + scoped_ptr<storage::BlobDataBuilder> blob_data( |
| new storage::BlobDataBuilder(response->blob_uuid)); |
| - match_context->response_body_buffer = new net::IOBufferWithSize(kBufferSize); |
| - |
| - disk_cache::Entry* tmp_entry_ptr = match_context->entry; |
| - net::IOBufferWithSize* response_body_buffer = |
| - match_context->response_body_buffer.get(); |
| - |
| - net::CompletionCallback read_callback = base::Bind( |
| - &CacheStorageCache::MatchDidReadResponseBodyData, |
| - weak_ptr_factory_.GetWeakPtr(), base::Passed(match_context.Pass())); |
| - |
| - int read_rv = |
| - tmp_entry_ptr->ReadData(INDEX_RESPONSE_BODY, 0, response_body_buffer, |
| - response_body_buffer->size(), read_callback); |
| - |
| - if (read_rv != net::ERR_IO_PENDING) |
| - read_callback.Run(read_rv); |
| -} |
| - |
| -void CacheStorageCache::MatchDidReadResponseBodyData( |
| - scoped_ptr<MatchContext> match_context, |
| - int rv) { |
| - if (rv < 0) { |
| - match_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE, |
| - scoped_ptr<ServiceWorkerResponse>(), |
| - scoped_ptr<storage::BlobDataHandle>()); |
| - return; |
| - } |
| - |
| - if (rv == 0) { |
| - match_context->response->blob_uuid = match_context->blob_data->uuid(); |
| - match_context->response->blob_size = match_context->total_bytes_read; |
| - MatchDoneWithBody(match_context.Pass()); |
| - return; |
| - } |
| - |
| - // TODO(jkarlin): This copying of the the entire cache response into memory is |
| - // awful. Create a new interface around SimpleCache that provides access the |
| - // data directly from the file. See bug http://crbug.com/403493. |
| - match_context->blob_data->AppendData( |
| - match_context->response_body_buffer->data(), rv); |
| - match_context->total_bytes_read += rv; |
| - int total_bytes_read = match_context->total_bytes_read; |
| - |
| - // Grab some pointers before passing match_context in bind. |
| - net::IOBufferWithSize* buffer = match_context->response_body_buffer.get(); |
| - disk_cache::Entry* tmp_entry_ptr = match_context->entry; |
| - |
| - net::CompletionCallback read_callback = base::Bind( |
| - &CacheStorageCache::MatchDidReadResponseBodyData, |
| - weak_ptr_factory_.GetWeakPtr(), base::Passed(match_context.Pass())); |
| - |
| - int read_rv = tmp_entry_ptr->ReadData(INDEX_RESPONSE_BODY, total_bytes_read, |
| - buffer, buffer->size(), read_callback); |
| - |
| - if (read_rv != net::ERR_IO_PENDING) |
| - read_callback.Run(read_rv); |
| -} |
| - |
| -void CacheStorageCache::MatchDoneWithBody( |
| - scoped_ptr<MatchContext> match_context) { |
| - if (!match_context->blob_storage_context) { |
| - match_context->original_callback.Run(CACHE_STORAGE_ERROR_STORAGE, |
| - scoped_ptr<ServiceWorkerResponse>(), |
| - scoped_ptr<storage::BlobDataHandle>()); |
| - return; |
| - } |
| + // Copy the Entry* before the scoped_ptr<> is passed to its DataHandle. |
| + disk_cache::Entry* tmp_entry = match_context->entry.get(); |
| + blob_data->AppendDiskCacheEntry( |
| + new CacheStorageCacheDataHandle(this, match_context->entry.Pass()), |
| + tmp_entry, INDEX_RESPONSE_BODY); |
| scoped_ptr<storage::BlobDataHandle> blob_data_handle( |
| - match_context->blob_storage_context->AddFinishedBlob( |
| - match_context->blob_data.get())); |
| - |
| - match_context->original_callback.Run(CACHE_STORAGE_OK, |
| - match_context->response.Pass(), |
| + blob_storage_context_->AddFinishedBlob(blob_data.get())); |
| + match_context->original_callback.Run(CACHE_STORAGE_OK, response.Pass(), |
| blob_data_handle.Pass()); |
| } |
| @@ -828,13 +747,14 @@ void CacheStorageCache::PutDidDelete(scoped_ptr<PutContext> put_context, |
| return; |
| } |
| - disk_cache::Entry** entry_ptr = &put_context->cache_entry; |
| + scoped_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(); |
| net::CompletionCallback create_entry_callback = base::Bind( |
| &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(), |
| - base::Passed(put_context.Pass())); |
| + base::Passed(scoped_entry_ptr.Pass()), base::Passed(put_context.Pass())); |
| int create_rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr, |
| create_entry_callback); |
| @@ -843,14 +763,15 @@ void CacheStorageCache::PutDidDelete(scoped_ptr<PutContext> put_context, |
| create_entry_callback.Run(create_rv); |
| } |
| -void CacheStorageCache::PutDidCreateEntry(scoped_ptr<PutContext> put_context, |
| - int rv) { |
| +void CacheStorageCache::PutDidCreateEntry( |
| + scoped_ptr<disk_cache::Entry*> entry_ptr, |
| + scoped_ptr<PutContext> put_context, |
| + int rv) { |
| if (rv != net::OK) { |
| put_context->callback.Run(CACHE_STORAGE_ERROR_EXISTS); |
| return; |
| } |
| - |
| - DCHECK(put_context->cache_entry); |
| + put_context->cache_entry.reset(*entry_ptr); |
| CacheMetadata metadata; |
| CacheRequest* request_metadata = metadata.mutable_request(); |
| @@ -891,7 +812,7 @@ void CacheStorageCache::PutDidCreateEntry(scoped_ptr<PutContext> put_context, |
| new net::StringIOBuffer(serialized.Pass())); |
| // Get a temporary copy of the entry pointer before passing it in base::Bind. |
| - disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry; |
| + disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry.get(); |
| net::CompletionCallback write_headers_callback = base::Bind( |
| &CacheStorageCache::PutDidWriteHeaders, weak_ptr_factory_.GetWeakPtr(), |
| @@ -931,8 +852,7 @@ void CacheStorageCache::PutDidWriteHeaders(scoped_ptr<PutContext> put_context, |
| DCHECK(put_context->blob_data_handle); |
| - disk_cache::ScopedEntryPtr entry(put_context->cache_entry); |
| - put_context->cache_entry = NULL; |
| + disk_cache::ScopedEntryPtr entry(put_context->cache_entry.Pass()); |
| scoped_ptr<BlobReader> reader(new BlobReader()); |
| BlobReader* reader_ptr = reader.get(); |
| @@ -956,7 +876,7 @@ void CacheStorageCache::PutDidWriteBlobToCache( |
| disk_cache::ScopedEntryPtr entry, |
| bool success) { |
| DCHECK(entry); |
| - put_context->cache_entry = entry.release(); |
| + put_context->cache_entry = entry.Pass(); |
| if (!success) { |
| put_context->cache_entry->Doom(); |