summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--webkit/appcache/appcache_group.cc21
-rw-r--r--webkit/appcache/appcache_group.h3
2 files changed, 15 insertions, 9 deletions
diff --git a/webkit/appcache/appcache_group.cc b/webkit/appcache/appcache_group.cc
index e1906ab..fd22563 100644
--- a/webkit/appcache/appcache_group.cc
+++ b/webkit/appcache/appcache_group.cc
@@ -44,7 +44,8 @@ AppCacheGroup::AppCacheGroup(AppCacheService* service,
newest_complete_cache_(NULL),
update_job_(NULL),
service_(service),
- restart_update_task_(NULL) {
+ restart_update_task_(NULL),
+ is_in_dtor_(false) {
service_->storage()->working_set()->AddGroup(this);
host_observer_.reset(new HostObserver(this));
}
@@ -55,6 +56,8 @@ AppCacheGroup::~AppCacheGroup() {
DCHECK(!restart_update_task_);
DCHECK(queued_updates_.empty());
+ is_in_dtor_ = true;
+
if (update_job_)
delete update_job_;
DCHECK_EQ(IDLE, update_status_);
@@ -153,6 +156,9 @@ void AppCacheGroup::AddNewlyDeletableResponseIds(
void AppCacheGroup::StartUpdateWithNewMasterEntry(
AppCacheHost* host, const GURL& new_master_resource) {
+ if (is_in_dtor_)
+ return;
+
if (!update_job_)
update_job_ = new AppCacheUpdateJob(service_, this);
@@ -245,15 +251,12 @@ void AppCacheGroup::SetUpdateStatus(UpdateStatus status) {
} else {
update_job_ = NULL;
- // Check member variable before notifying observers about update finishing.
- // Observers may remove reference to group, causing group to be deleted
- // after the notifications. If there are queued updates, then the group
- // will continue to exist.
- bool restart_update = !queued_updates_.empty();
-
+ // Observers may release us in these callbacks, so we protect against
+ // deletion by adding an extra ref in this scope (but only if we're not
+ // in our destructor).
+ scoped_refptr<AppCacheGroup> protect(is_in_dtor_ ? NULL : this);
FOR_EACH_OBSERVER(UpdateObserver, observers_, OnUpdateComplete(this));
-
- if (restart_update)
+ if (!queued_updates_.empty())
ScheduleUpdateRestart(kUpdateRestartDelayMs);
}
}
diff --git a/webkit/appcache/appcache_group.h b/webkit/appcache/appcache_group.h
index 3392eea..8d620a8 100644
--- a/webkit/appcache/appcache_group.h
+++ b/webkit/appcache/appcache_group.h
@@ -136,6 +136,9 @@ class AppCacheGroup : public base::RefCounted<AppCacheGroup> {
CancelableTask* restart_update_task_;
scoped_ptr<HostObserver> host_observer_;
+ // True if we're in our destructor.
+ bool is_in_dtor_;
+
FRIEND_TEST(AppCacheGroupTest, StartUpdate);
FRIEND_TEST(AppCacheGroupTest, CancelUpdate);
FRIEND_TEST(AppCacheGroupTest, QueueUpdate);