| Index: content/browser/service_worker/service_worker_cache.cc
|
| diff --git a/content/browser/service_worker/service_worker_cache.cc b/content/browser/service_worker/service_worker_cache.cc
|
| index 6bf5acbe9e517b6e5c03b928dcd8e1a8f4a66bba..4fc31cf0ac679dac3e64372f85644be0ca01b213 100644
|
| --- a/content/browser/service_worker/service_worker_cache.cc
|
| +++ b/content/browser/service_worker/service_worker_cache.cc
|
| @@ -55,8 +55,7 @@ struct ResponseReadContext {
|
| // Streams data from a blob and writes it to a given disk_cache::Entry.
|
| class BlobReader : public net::URLRequest::Delegate {
|
| public:
|
| - typedef base::Callback<void(disk_cache::ScopedEntryPtr, bool)>
|
| - EntryBoolCallback;
|
| + typedef base::Callback<void(bool)> BoolCallback;
|
|
|
| BlobReader(disk_cache::ScopedEntryPtr entry)
|
| : cache_entry_offset_(0),
|
| @@ -68,7 +67,7 @@ class BlobReader : public net::URLRequest::Delegate {
|
|
|
| void StreamBlobToCache(net::URLRequestContext* request_context,
|
| scoped_ptr<storage::BlobDataHandle> blob_data_handle,
|
| - const EntryBoolCallback& callback) {
|
| + const BoolCallback& callback) {
|
| callback_ = callback;
|
| blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest(
|
| blob_data_handle.Pass(), request_context, this);
|
| @@ -102,7 +101,7 @@ class BlobReader : public net::URLRequest::Delegate {
|
|
|
| virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE {
|
| if (!request->status().is_success()) {
|
| - callback_.Run(entry_.Pass(), false);
|
| + callback_.Run(false);
|
| return;
|
| }
|
| ReadFromBlob();
|
| @@ -119,12 +118,12 @@ class BlobReader : public net::URLRequest::Delegate {
|
| virtual void OnReadCompleted(net::URLRequest* request,
|
| int bytes_read) OVERRIDE {
|
| if (!request->status().is_success()) {
|
| - callback_.Run(entry_.Pass(), false);
|
| + callback_.Run(false);
|
| return;
|
| }
|
|
|
| if (bytes_read == 0) {
|
| - callback_.Run(entry_.Pass(), true);
|
| + callback_.Run(true);
|
| return;
|
| }
|
|
|
| @@ -145,7 +144,7 @@ class BlobReader : public net::URLRequest::Delegate {
|
|
|
| void DidWriteDataToEntry(int expected_bytes, int rv) {
|
| if (rv != expected_bytes) {
|
| - callback_.Run(entry_.Pass(), false);
|
| + callback_.Run(false);
|
| return;
|
| }
|
|
|
| @@ -157,29 +156,51 @@ class BlobReader : public net::URLRequest::Delegate {
|
| int cache_entry_offset_;
|
| disk_cache::ScopedEntryPtr entry_;
|
| scoped_ptr<net::URLRequest> blob_request_;
|
| - EntryBoolCallback callback_;
|
| + BoolCallback callback_;
|
| scoped_refptr<net::IOBufferWithSize> buffer_;
|
| base::WeakPtrFactory<BlobReader> weak_ptr_factory_;
|
| };
|
|
|
| +// The state needed to pass between ServiceWorkerCache::Put callbacks.
|
| +struct PutContext {
|
| + PutContext(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| + scoped_ptr<ServiceWorkerResponse> response,
|
| + scoped_ptr<storage::BlobDataHandle> blob_data_handle,
|
| + const ServiceWorkerCache::ErrorCallback& callback,
|
| + net::URLRequestContext* request_context)
|
| + : request(request.Pass()),
|
| + response(response.Pass()),
|
| + blob_data_handle(blob_data_handle.Pass()),
|
| + callback(callback),
|
| + request_context(request_context),
|
| + cache_entry(NULL) {}
|
| + ~PutContext() {
|
| + if (cache_entry)
|
| + cache_entry->Close();
|
| + }
|
| +
|
| + // Input parameters to the Put function.
|
| + scoped_ptr<ServiceWorkerFetchRequest> request;
|
| + scoped_ptr<ServiceWorkerResponse> response;
|
| + scoped_ptr<storage::BlobDataHandle> blob_data_handle;
|
| + ServiceWorkerCache::ErrorCallback callback;
|
| +
|
| + net::URLRequestContext* request_context;
|
| +
|
| + // This isn't a scoped_ptr because the disk_cache needs an Entry** as input to
|
| + // CreateEntry.
|
| + disk_cache::Entry* cache_entry;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PutContext);
|
| +};
|
| +
|
| // Put callbacks
|
| -void PutDidCreateEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| - scoped_ptr<ServiceWorkerResponse> response,
|
| - const ServiceWorkerCache::ErrorCallback& callback,
|
| - scoped_ptr<disk_cache::Entry*> entryptr,
|
| - scoped_ptr<storage::BlobDataHandle> blob_data_handle,
|
| - net::URLRequestContext* request_context,
|
| - int rv);
|
| -void PutDidWriteHeaders(scoped_ptr<ServiceWorkerResponse> response,
|
| - const ServiceWorkerCache::ErrorCallback& callback,
|
| - disk_cache::ScopedEntryPtr entry,
|
| - scoped_ptr<storage::BlobDataHandle> blob_data_handle,
|
| - net::URLRequestContext* request_context,
|
| +void PutDidCreateEntry(scoped_ptr<PutContext> put_context, int rv);
|
| +void PutDidWriteHeaders(scoped_ptr<PutContext> put_context,
|
| int expected_bytes,
|
| int rv);
|
| -void PutDidWriteBlobToCache(const ServiceWorkerCache::ErrorCallback& callback,
|
| +void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context,
|
| scoped_ptr<BlobReader> blob_reader,
|
| - disk_cache::ScopedEntryPtr entry,
|
| bool success);
|
|
|
| // Match callbacks
|
| @@ -229,28 +250,22 @@ void CreateBackendDidCreate(const ServiceWorkerCache::ErrorCallback& callback,
|
| base::WeakPtr<ServiceWorkerCache> cache,
|
| int rv);
|
|
|
| -void PutDidCreateEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| - scoped_ptr<ServiceWorkerResponse> response,
|
| - const ServiceWorkerCache::ErrorCallback& callback,
|
| - scoped_ptr<disk_cache::Entry*> entryptr,
|
| - scoped_ptr<storage::BlobDataHandle> blob_data_handle,
|
| - net::URLRequestContext* request_context,
|
| - int rv) {
|
| +void PutDidCreateEntry(scoped_ptr<PutContext> put_context, int rv) {
|
| if (rv != net::OK) {
|
| - callback.Run(ServiceWorkerCache::ErrorTypeExists);
|
| + put_context->callback.Run(ServiceWorkerCache::ErrorTypeExists);
|
| return;
|
| }
|
|
|
| - DCHECK(entryptr);
|
| - disk_cache::ScopedEntryPtr entry(*entryptr);
|
| + DCHECK(put_context->cache_entry);
|
|
|
| ServiceWorkerRequestResponseHeaders headers;
|
| - headers.set_method(request->method);
|
| + headers.set_method(put_context->request->method);
|
|
|
| - headers.set_status_code(response->status_code);
|
| - headers.set_status_text(response->status_text);
|
| - for (ServiceWorkerHeaderMap::const_iterator it = request->headers.begin();
|
| - it != request->headers.end();
|
| + headers.set_status_code(put_context->response->status_code);
|
| + headers.set_status_text(put_context->response->status_text);
|
| + for (ServiceWorkerHeaderMap::const_iterator it =
|
| + put_context->request->headers.begin();
|
| + it != put_context->request->headers.end();
|
| ++it) {
|
| ServiceWorkerRequestResponseHeaders::HeaderMap* header_map =
|
| headers.add_request_headers();
|
| @@ -258,8 +273,9 @@ void PutDidCreateEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| header_map->set_value(it->second);
|
| }
|
|
|
| - for (ServiceWorkerHeaderMap::const_iterator it = response->headers.begin();
|
| - it != response->headers.end();
|
| + for (ServiceWorkerHeaderMap::const_iterator it =
|
| + put_context->response->headers.begin();
|
| + it != put_context->response->headers.end();
|
| ++it) {
|
| ServiceWorkerRequestResponseHeaders::HeaderMap* header_map =
|
| headers.add_response_headers();
|
| @@ -269,7 +285,7 @@ void PutDidCreateEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
|
|
|
| scoped_ptr<std::string> serialized(new std::string());
|
| if (!headers.SerializeToString(serialized.get())) {
|
| - callback.Run(ServiceWorkerCache::ErrorTypeStorage);
|
| + put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage);
|
| return;
|
| }
|
|
|
| @@ -277,16 +293,10 @@ void PutDidCreateEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| 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 = entry.get();
|
| + disk_cache::Entry* tmp_entry_ptr = put_context->cache_entry;
|
|
|
| - net::CompletionCallback write_headers_callback =
|
| - base::Bind(PutDidWriteHeaders,
|
| - base::Passed(response.Pass()),
|
| - callback,
|
| - base::Passed(entry.Pass()),
|
| - base::Passed(blob_data_handle.Pass()),
|
| - request_context,
|
| - buffer->size());
|
| + net::CompletionCallback write_headers_callback = base::Bind(
|
| + PutDidWriteHeaders, base::Passed(put_context.Pass()), buffer->size());
|
|
|
| rv = tmp_entry_ptr->WriteData(INDEX_HEADERS,
|
| 0 /* offset */,
|
| @@ -299,50 +309,53 @@ void PutDidCreateEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| write_headers_callback.Run(rv);
|
| }
|
|
|
| -void PutDidWriteHeaders(scoped_ptr<ServiceWorkerResponse> response,
|
| - const ServiceWorkerCache::ErrorCallback& callback,
|
| - disk_cache::ScopedEntryPtr entry,
|
| - scoped_ptr<storage::BlobDataHandle> blob_data_handle,
|
| - net::URLRequestContext* request_context,
|
| +void PutDidWriteHeaders(scoped_ptr<PutContext> put_context,
|
| int expected_bytes,
|
| int rv) {
|
| if (rv != expected_bytes) {
|
| - entry->Doom();
|
| - callback.Run(ServiceWorkerCache::ErrorTypeStorage);
|
| + put_context->cache_entry->Doom();
|
| + put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage);
|
| return;
|
| }
|
|
|
| // The metadata is written, now for the response content. The data is streamed
|
| // from the blob into the cache entry.
|
|
|
| - if (response->blob_uuid.empty()) {
|
| - callback.Run(ServiceWorkerCache::ErrorTypeOK);
|
| + if (put_context->response->blob_uuid.empty()) {
|
| + put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK);
|
| return;
|
| }
|
|
|
| - DCHECK(blob_data_handle);
|
| + DCHECK(put_context->blob_data_handle);
|
|
|
| + disk_cache::ScopedEntryPtr entry(put_context->cache_entry);
|
| + put_context->cache_entry = NULL;
|
| scoped_ptr<BlobReader> reader(new BlobReader(entry.Pass()));
|
| +
|
| BlobReader* reader_ptr = reader.get();
|
|
|
| - reader_ptr->StreamBlobToCache(
|
| - request_context,
|
| - blob_data_handle.Pass(),
|
| - base::Bind(
|
| - PutDidWriteBlobToCache, callback, base::Passed(reader.Pass())));
|
| + // Grab some pointers before passing put_context in Bind.
|
| + net::URLRequestContext* request_context = put_context->request_context;
|
| + scoped_ptr<storage::BlobDataHandle> blob_data_handle =
|
| + put_context->blob_data_handle.Pass();
|
| +
|
| + reader_ptr->StreamBlobToCache(request_context,
|
| + blob_data_handle.Pass(),
|
| + base::Bind(PutDidWriteBlobToCache,
|
| + base::Passed(put_context.Pass()),
|
| + base::Passed(reader.Pass())));
|
| }
|
|
|
| -void PutDidWriteBlobToCache(const ServiceWorkerCache::ErrorCallback& callback,
|
| +void PutDidWriteBlobToCache(scoped_ptr<PutContext> put_context,
|
| scoped_ptr<BlobReader> blob_reader,
|
| - disk_cache::ScopedEntryPtr entry,
|
| bool success) {
|
| if (!success) {
|
| - entry->Doom();
|
| - callback.Run(ServiceWorkerCache::ErrorTypeStorage);
|
| + put_context->cache_entry->Doom();
|
| + put_context->callback.Run(ServiceWorkerCache::ErrorTypeStorage);
|
| return;
|
| }
|
|
|
| - callback.Run(ServiceWorkerCache::ErrorTypeOK);
|
| + put_context->callback.Run(ServiceWorkerCache::ErrorTypeOK);
|
| }
|
|
|
| void MatchDidOpenEntry(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| @@ -669,6 +682,8 @@ struct ServiceWorkerCache::KeysContext {
|
| // Used for enumerating cache entries.
|
| scoped_ptr<disk_cache::Backend::Iterator> backend_iterator;
|
| disk_cache::Entry* enumerated_entry;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(KeysContext);
|
| };
|
|
|
| // static
|
| @@ -699,7 +714,6 @@ void ServiceWorkerCache::Put(scoped_ptr<ServiceWorkerFetchRequest> request,
|
| scoped_ptr<ServiceWorkerResponse> response,
|
| const ErrorCallback& callback) {
|
| scoped_ptr<storage::BlobDataHandle> blob_data_handle;
|
| -
|
| if (!response->blob_uuid.empty()) {
|
| if (!blob_storage_context_) {
|
| callback.Run(ErrorTypeStorage);
|
| @@ -857,20 +871,17 @@ void ServiceWorkerCache::PutImpl(
|
| return;
|
| }
|
|
|
| - scoped_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*);
|
| -
|
| - disk_cache::Entry** entry_ptr = entry.get();
|
| + scoped_ptr<PutContext> put_context(new PutContext(request.Pass(),
|
| + response.Pass(),
|
| + blob_data_handle.Pass(),
|
| + callback,
|
| + request_context_));
|
|
|
| - ServiceWorkerFetchRequest* request_ptr = request.get();
|
| + disk_cache::Entry** entry_ptr = &put_context->cache_entry;
|
| + ServiceWorkerFetchRequest* request_ptr = put_context->request.get();
|
|
|
| net::CompletionCallback create_entry_callback =
|
| - base::Bind(PutDidCreateEntry,
|
| - base::Passed(request.Pass()),
|
| - base::Passed(response.Pass()),
|
| - callback,
|
| - base::Passed(entry.Pass()),
|
| - base::Passed(blob_data_handle.Pass()),
|
| - request_context_);
|
| + base::Bind(PutDidCreateEntry, base::Passed(put_context.Pass()));
|
|
|
| int rv = backend_->CreateEntry(
|
| request_ptr->url.spec(), entry_ptr, create_entry_callback);
|
|
|