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..d921ade105a7cc06d9af15249a52edba289ba50e 100644 |
--- a/content/browser/cache_storage/cache_storage_cache.cc |
+++ b/content/browser/cache_storage/cache_storage_cache.cc |
@@ -32,8 +32,16 @@ namespace content { |
namespace { |
-typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)> |
- EntryBoolCallback; |
+class CacheStorageCacheExtraData : public storage::BlobDataBuilder::ExtraData { |
+ public: |
+ explicit CacheStorageCacheExtraData( |
+ const scoped_refptr<CacheStorageCache>& cache) |
+ : cache_(cache) {} |
+ |
+ private: |
+ scoped_refptr<CacheStorageCache> cache_; |
+}; |
+ |
typedef base::Callback<void(scoped_ptr<CacheMetadata>)> MetadataCallback; |
enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY }; |
@@ -85,15 +93,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,22 +128,6 @@ 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); |
- |
- if (read_rv != net::ERR_IO_PENDING) |
- read_header_callback.Run(read_rv); |
-} |
- |
void ReadMetadataDidReadMetadata( |
disk_cache::Entry* entry, |
const MetadataCallback& callback, |
@@ -165,6 +148,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 +305,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 +331,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 +341,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 +554,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 +572,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 +582,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 +600,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 +633,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 +706,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 +727,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 +743,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(); |
@@ -887,7 +792,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 +832,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 +855,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(); |