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 43737590ee9e623cb06cf61829947c37f73cf3cb..7189e98f92171ff6bf6f25062d88459eebe437d2 100644 |
| --- a/content/browser/cache_storage/cache_storage_cache.cc |
| +++ b/content/browser/cache_storage/cache_storage_cache.cc |
| @@ -32,11 +32,17 @@ namespace content { |
| namespace { |
| -typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> |
| - EntryBoolCallback; |
| -typedef base::Callback<void(scoped_ptr<CacheMetadata>)> MetadataCallback; |
| +class CacheStorageCacheExtraData : public storage::BlobDataBuilder::ExtraData { |
| + public: |
| + explicit CacheStorageCacheExtraData( |
| + const scoped_refptr<CacheStorageCache>& cache) |
| + : cache_(cache) {} |
| -enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; |
| + private: |
| + scoped_refptr<CacheStorageCache> cache_; |
| +}; |
| + |
| +typedef base::Callback<void(scoped_ptr<CacheMetadata>)> MetadataCallback; |
| // The maximum size of an individual cache. Ultimately cache size is controlled |
| // per-origin. |
| @@ -85,15 +91,6 @@ CacheResponse::ResponseType WebResponseTypeToProtoResponseType( |
| return CacheResponse::OPAQUE_TYPE; |
| } |
| -// Copy headers out of a cache entry and into a protobuf. The callback is |
| -// guaranteed to be run. |
| -void ReadMetadata(disk_cache::Entry* entry, const MetadataCallback& callback); |
| -void ReadMetadataDidReadMetadata( |
| - disk_cache::Entry* entry, |
| - const MetadataCallback& callback, |
| - const scoped_refptr<net::IOBufferWithSize>& buffer, |
| - int rv); |
| - |
| bool VaryMatches(const ServiceWorkerHeaderMap& request, |
| const ServiceWorkerHeaderMap& cached_request, |
| const ServiceWorkerHeaderMap& response) { |
| @@ -129,21 +126,9 @@ bool VaryMatches(const ServiceWorkerHeaderMap& request, |
| return true; |
| } |
| -void ReadMetadata(disk_cache::Entry* entry, const MetadataCallback& callback) { |
| - DCHECK(entry); |
| - |
| - scoped_refptr<net::IOBufferWithSize> buffer( |
| - new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS))); |
| - |
| - net::CompletionCallback read_header_callback = |
| - base::Bind(ReadMetadataDidReadMetadata, entry, callback, buffer); |
| - |
| - int read_rv = entry->ReadData(INDEX_HEADERS, 0, buffer.get(), buffer->size(), |
| - read_header_callback); |
| +typedef base::Callback<void(scoped_ptr<CacheMetadata>)> MetadataCallback; |
|
jkarlin
2015/05/29 14:59:41
Why move this? I prefer to have typdefs and enums
gavinp
2015/05/29 18:06:07
I moved it back.
The reason I moved it down was f
|
| - if (read_rv != net::ERR_IO_PENDING) |
| - read_header_callback.Run(read_rv); |
| -} |
| +enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; |
|
jkarlin
2015/05/29 14:59:41
Ditto.
gavinp
2015/05/29 18:06:07
Done.
|
| void ReadMetadataDidReadMetadata( |
| disk_cache::Entry* entry, |
| @@ -165,6 +150,24 @@ void ReadMetadataDidReadMetadata( |
| callback.Run(metadata.Pass()); |
| } |
| +// Copy headers out of a cache entry and into a protobuf. The callback is |
| +// guaranteed to be run. |
| +void ReadMetadata(disk_cache::Entry* entry, const MetadataCallback& callback) { |
| + DCHECK(entry); |
| + |
| + scoped_refptr<net::IOBufferWithSize> buffer( |
| + new net::IOBufferWithSize(entry->GetDataSize(INDEX_HEADERS))); |
| + |
| + net::CompletionCallback read_header_callback = |
| + base::Bind(ReadMetadataDidReadMetadata, entry, callback, buffer); |
| + |
| + int read_rv = entry->ReadData(INDEX_HEADERS, 0, buffer.get(), buffer->size(), |
| + read_header_callback); |
| + |
| + if (read_rv != net::ERR_IO_PENDING) |
| + read_header_callback.Run(read_rv); |
| +} |
| + |
| } // namespace |
| // Streams data from a blob and writes it to a given disk_cache::Entry. |
| @@ -304,32 +307,12 @@ struct CacheStorageCache::KeysContext { |
| struct CacheStorageCache::MatchContext { |
| 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); |
| }; |
| @@ -350,12 +333,7 @@ struct CacheStorageCache::PutContext { |
| blob_data_handle(blob_data_handle.Pass()), |
| callback(callback), |
| request_context(request_context), |
| - 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; |
| @@ -365,10 +343,7 @@ struct CacheStorageCache::PutContext { |
| CacheStorageCache::ErrorCallback callback; |
| net::URLRequestContext* request_context; |
| 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); |
| }; |
| @@ -581,13 +556,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, |
| @@ -597,6 +574,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) { |
| @@ -606,15 +584,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( |
| @@ -627,29 +602,27 @@ 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()); |
| for (int i = 0; i < metadata->response().headers_size(); ++i) { |
| const CacheHeaderMap header = metadata->response().headers(i); |
| - DCHECK(header.name().find('\0') == std::string::npos); |
| - DCHECK(header.value().find('\0') == std::string::npos); |
| + DCHECK_EQ(std::string::npos, header.name().find('\0')); |
| + DCHECK_EQ(std::string::npos, header.value().find('\0')); |
| response->headers.insert(std::make_pair(header.name(), header.value())); |
| } |
| ServiceWorkerHeaderMap cached_request_headers; |
| for (int i = 0; i < metadata->request().headers_size(); ++i) { |
| const CacheHeaderMap header = metadata->request().headers(i); |
| - DCHECK(header.name().find('\0') == std::string::npos); |
| - DCHECK(header.value().find('\0') == std::string::npos); |
| + DCHECK_EQ(std::string::npos, header.name().find('\0')); |
| + DCHECK_EQ(std::string::npos, header.value().find('\0')); |
| cached_request_headers[header.name()] = header.value(); |
| } |
| @@ -662,97 +635,29 @@ 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; |
| - } |
| - |
| + blob_data->AppendDiskCacheEntry( |
| + match_context->entry.Pass(), INDEX_RESPONSE_BODY, |
| + make_scoped_ptr(new CacheStorageCacheExtraData(this))); |
| 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()); |
| } |
| @@ -803,7 +708,7 @@ void CacheStorageCache::Put(const CacheStorageBatchOperation& operation, |
| } |
| void CacheStorageCache::PutImpl(scoped_ptr<PutContext> put_context) { |
| - DCHECK(backend_state_ != BACKEND_UNINITIALIZED); |
| + DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); |
| if (backend_state_ != BACKEND_OPEN) { |
| put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); |
| return; |
| @@ -824,13 +729,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); |
| @@ -839,14 +745,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.get()); |
|
jkarlin
2015/05/29 14:59:41
reset(*entry_ptr)
gavinp
2015/05/29 18:06:07
Done.
|
| CacheMetadata metadata; |
| CacheRequest* request_metadata = metadata.mutable_request(); |
| @@ -887,7 +794,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(), |
| @@ -927,8 +834,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(); |
| @@ -951,7 +857,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(); |