ServiceWorker: Check the existence of the disk cache before access
This CL wraps AppCacheDiskCacheInterface with base::WeakPtr and makes
AppCacheResponseIO check it before access to avoid a crash.
<Before this CL>
Derivatives of AppCacheResponseIO (ServiceWorkerResponseWriter etc) has a raw
pointer to AppCacheDiskCacheInterface implementation and the implementation is
owned by storage implementation, namely, AppCacheStorageImpl or
ServiceWorkerStorage.
When ServiceWorkerStorage is destroyed because of storage recovery while
ServiceWorkerCacheWriter is asynchronously running, the cache writer asks the
response writer to store data in the disk cache and it crashes because of the
dangling pointer.
<After this CL>
ServiceWorkerResponseWriter checks the existence of the disk cache by
base::WeakPtr before access and simply fails the request if it is already gone.
BUG=600542
Review URL: https://codereview.chromium.org/1864613003
Cr-Commit-Position: refs/heads/master@{#385638}
diff --git a/content/browser/appcache/appcache_response.h b/content/browser/appcache/appcache_response.h
index 8543b2b9..0b709b9 100644
--- a/content/browser/appcache/appcache_response.h
+++ b/content/browser/appcache/appcache_response.h
@@ -93,6 +93,8 @@
virtual ~Entry() {}
};
+ AppCacheDiskCacheInterface();
+
virtual int CreateEntry(int64_t key,
Entry** entry,
const net::CompletionCallback& callback) = 0;
@@ -102,9 +104,12 @@
virtual int DoomEntry(int64_t key,
const net::CompletionCallback& callback) = 0;
+ base::WeakPtr<AppCacheDiskCacheInterface> GetWeakPtr();
+
protected:
- friend class base::RefCounted<AppCacheDiskCacheInterface>;
- virtual ~AppCacheDiskCacheInterface() {}
+ virtual ~AppCacheDiskCacheInterface();
+
+ base::WeakPtrFactory<AppCacheDiskCacheInterface> weak_factory_;
};
// Common base class for response reader and writer.
@@ -114,9 +119,10 @@
int64_t response_id() const { return response_id_; }
protected:
- AppCacheResponseIO(int64_t response_id,
- int64_t group_id,
- AppCacheDiskCacheInterface* disk_cache);
+ AppCacheResponseIO(
+ int64_t response_id,
+ int64_t group_id,
+ const base::WeakPtr<AppCacheDiskCacheInterface>& disk_cache);
virtual void OnIOComplete(int result) = 0;
virtual void OnOpenEntryComplete() {}
@@ -130,7 +136,7 @@
const int64_t response_id_;
const int64_t group_id_;
- AppCacheDiskCacheInterface* disk_cache_;
+ base::WeakPtr<AppCacheDiskCacheInterface> disk_cache_;
AppCacheDiskCacheInterface::Entry* entry_;
scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_;
scoped_refptr<net::IOBuffer> buffer_;
@@ -190,9 +196,10 @@
friend class content::MockAppCacheStorage;
// Should only be constructed by the storage class and derivatives.
- AppCacheResponseReader(int64_t response_id,
- int64_t group_id,
- AppCacheDiskCacheInterface* disk_cache);
+ AppCacheResponseReader(
+ int64_t response_id,
+ int64_t group_id,
+ const base::WeakPtr<AppCacheDiskCacheInterface>& disk_cache);
void OnIOComplete(int result) override;
void OnOpenEntryComplete() override;
@@ -247,9 +254,10 @@
protected:
// Should only be constructed by the storage class and derivatives.
- AppCacheResponseWriter(int64_t response_id,
- int64_t group_id,
- AppCacheDiskCacheInterface* disk_cache);
+ AppCacheResponseWriter(
+ int64_t response_id,
+ int64_t group_id,
+ const base::WeakPtr<AppCacheDiskCacheInterface>& disk_cache);
private:
friend class AppCacheStorageImpl;
@@ -304,10 +312,12 @@
protected:
friend class AppCacheStorageImpl;
friend class content::MockAppCacheStorage;
+
// Should only be constructed by the storage class and derivatives.
- AppCacheResponseMetadataWriter(int64_t response_id,
- int64_t group_id,
- AppCacheDiskCacheInterface* disk_cache);
+ AppCacheResponseMetadataWriter(
+ int64_t response_id,
+ int64_t group_id,
+ const base::WeakPtr<AppCacheDiskCacheInterface>& disk_cache);
private:
void OnIOComplete(int result) override;