Index: webkit/quota/usage_tracker.cc |
diff --git a/webkit/quota/usage_tracker.cc b/webkit/quota/usage_tracker.cc |
index 07a71d8724e5c13210dd9b1c9ab8422de3c3f016..826d9698f377aeb6494afc50aa65f7ccee50fd60 100644 |
--- a/webkit/quota/usage_tracker.cc |
+++ b/webkit/quota/usage_tracker.cc |
@@ -29,11 +29,11 @@ void DidGetOriginUsage(const OriginUsageAccumulator& accumulator, |
} |
void DidGetHostUsage(const UsageCallback& callback, |
- int64 cached_usage, |
- int64 non_cached_usage) { |
- DCHECK_GE(cached_usage, 0); |
- DCHECK_GE(non_cached_usage, 0); |
- callback.Run(cached_usage + non_cached_usage); |
+ int64 limited_usage, |
+ int64 unlimited_usage) { |
+ DCHECK_GE(limited_usage, 0); |
+ DCHECK_GE(unlimited_usage, 0); |
+ callback.Run(limited_usage + unlimited_usage); |
} |
void NoopHostUsageCallback(int64 usage) {} |
@@ -95,7 +95,35 @@ ClientUsageTracker* UsageTracker::GetClientTracker(QuotaClient::ID client_id) { |
} |
void UsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { |
- GetGlobalUsage(base::Bind(&DidGetGlobalUsageForLimitedGlobalUsage, callback)); |
+ if (global_usage_callbacks_.HasCallbacks()) { |
+ global_usage_callbacks_.Add(base::Bind( |
+ &DidGetGlobalUsageForLimitedGlobalUsage, callback)); |
+ return; |
+ } |
+ |
+ if (!global_limited_usage_callbacks_.Add(callback)) |
+ return; |
+ |
+ AccumulateInfo* info = new AccumulateInfo; |
+ // Calling GetGlobalLimitedUsage(accumulator) may synchronously |
+ // return if the usage is cached, which may in turn dispatch |
+ // the completion callback before we finish looping over |
+ // all clients (because info->pending_clients may reach 0 |
+ // during the loop). |
+ // To avoid this, we add one more pending client as a sentinel |
+ // and fire the sentinel callback at the end. |
+ info->pending_clients = client_tracker_map_.size() + 1; |
+ UsageCallback accumulator = base::Bind( |
+ &UsageTracker::AccumulateClientGlobalLimitedUsage, |
+ weak_factory_.GetWeakPtr(), base::Owned(info)); |
+ |
+ for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); |
+ iter != client_tracker_map_.end(); |
+ ++iter) |
+ iter->second->GetGlobalLimitedUsage(accumulator); |
+ |
+ // Fire the sentinel as we've now called GetGlobalUsage for all clients. |
+ accumulator.Run(0); |
kinuko
2013/05/30 05:56:32
Hmm, can we possibly cleanup this pattern in a sep
|
} |
void UsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { |
@@ -186,12 +214,22 @@ void UsageTracker::SetUsageCacheEnabled(QuotaClient::ID client_id, |
client_tracker->SetUsageCacheEnabled(origin, enabled); |
} |
+void UsageTracker::AccumulateClientGlobalLimitedUsage(AccumulateInfo* info, |
+ int64 limited_usage) { |
+ info->usage += limited_usage; |
+ if (--info->pending_clients) |
+ return; |
+ |
+ // All the clients have returned their usage data. Dispatch the |
+ // pending callbacks. |
+ global_limited_usage_callbacks_.Run(MakeTuple(info->usage)); |
+} |
+ |
void UsageTracker::AccumulateClientGlobalUsage(AccumulateInfo* info, |
int64 usage, |
int64 unlimited_usage) { |
info->usage += usage; |
info->unlimited_usage += unlimited_usage; |
- |
if (--info->pending_clients) |
return; |
@@ -250,6 +288,35 @@ ClientUsageTracker::~ClientUsageTracker() { |
special_storage_policy_->RemoveObserver(this); |
} |
+void ClientUsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { |
+ if (!global_usage_retrieved_) { |
+ GetGlobalUsage(base::Bind(&DidGetGlobalUsageForLimitedGlobalUsage, |
+ callback)); |
+ return; |
+ } |
+ |
+ if (non_cached_limited_origins_by_host_.empty()) { |
+ callback.Run(global_limited_usage_); |
+ return; |
+ } |
+ |
+ AccumulateInfo* info = new AccumulateInfo; |
+ info->pending_jobs = non_cached_limited_origins_by_host_.size() + 1; |
+ UsageCallback accumulator = base::Bind( |
+ &ClientUsageTracker::AccumulateLimitedOriginUsage, AsWeakPtr(), |
+ base::Owned(info), callback); |
+ |
+ for (OriginSetByHost::iterator host_itr = |
+ non_cached_limited_origins_by_host_.begin(); |
+ host_itr != non_cached_limited_origins_by_host_.end(); ++host_itr) { |
+ for (std::set<GURL>::iterator origin_itr = host_itr->second.begin(); |
+ origin_itr != host_itr->second.end(); ++origin_itr) |
+ client_->GetOriginUsage(*origin_itr, type_, accumulator); |
+ } |
+ |
+ accumulator.Run(global_limited_usage_); |
+} |
+ |
void ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { |
if (global_usage_retrieved_ && |
non_cached_limited_origins_by_host_.empty() && |
@@ -274,8 +341,8 @@ void ClientUsageTracker::GetHostUsage( |
return; |
} |
- if (!host_usage_accumulators_.Add(host, base::Bind( |
- &DidGetHostUsage, callback))) |
+ if (!host_usage_accumulators_.Add( |
+ host, base::Bind(&DidGetHostUsage, callback))) |
return; |
client_->GetOriginsForHost(type_, host, base::Bind( |
&ClientUsageTracker::DidGetOriginsForHostUsage, AsWeakPtr(), host)); |
@@ -362,6 +429,17 @@ void ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin, |
} |
} |
+void ClientUsageTracker::AccumulateLimitedOriginUsage( |
+ AccumulateInfo* info, |
+ const UsageCallback& callback, |
+ int64 usage) { |
+ info->limited_usage += usage; |
+ if (--info->pending_jobs) |
+ return; |
+ |
+ callback.Run(info->limited_usage); |
+} |
+ |
void ClientUsageTracker::DidGetOriginsForGlobalUsage( |
const GlobalUsageCallback& callback, |
const std::set<GURL>& origins) { |
@@ -394,23 +472,19 @@ void ClientUsageTracker::DidGetOriginsForGlobalUsage( |
void ClientUsageTracker::AccumulateHostUsage( |
AccumulateInfo* info, |
const GlobalUsageCallback& callback, |
- int64 cached_usage, |
- int64 non_cached_usage) { |
- info->cached_usage += cached_usage; |
- info->non_cached_usage += non_cached_usage; |
+ int64 limited_usage, |
+ int64 unlimited_usage) { |
+ info->limited_usage += limited_usage; |
+ info->unlimited_usage += unlimited_usage; |
if (--info->pending_jobs) |
return; |
- int64 total_usage = info->cached_usage + info->non_cached_usage; |
- int64 unlimited_usage = global_unlimited_usage_ + info->non_cached_usage; |
- |
- DCHECK_GE(total_usage, 0); |
- DCHECK_GE(unlimited_usage, 0); |
- if (unlimited_usage > total_usage) |
- unlimited_usage = total_usage; |
+ DCHECK_GE(info->limited_usage, 0); |
+ DCHECK_GE(info->unlimited_usage, 0); |
global_usage_retrieved_ = true; |
- callback.Run(total_usage, unlimited_usage); |
+ callback.Run(info->limited_usage + info->unlimited_usage, |
+ info->unlimited_usage); |
} |
void ClientUsageTracker::DidGetOriginsForHostUsage( |
@@ -458,25 +532,24 @@ void ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo* info, |
if (usage < 0) |
usage = 0; |
- if (IsUsageCacheEnabledForOrigin(origin)) { |
- info->cached_usage += usage; |
+ if (IsStorageUnlimited(origin)) |
+ info->unlimited_usage += usage; |
+ else |
+ info->limited_usage += usage; |
+ if (IsUsageCacheEnabledForOrigin(origin)) |
AddCachedOrigin(origin, usage); |
- } else { |
- info->non_cached_usage += usage; |
- } |
} |
if (--info->pending_jobs) |
return; |
AddCachedHost(host); |
host_usage_accumulators_.Run( |
- host, MakeTuple(info->cached_usage, info->non_cached_usage)); |
+ host, MakeTuple(info->limited_usage, info->unlimited_usage)); |
} |
void ClientUsageTracker::AddCachedOrigin( |
const GURL& origin, int64 new_usage) { |
- if (!IsUsageCacheEnabledForOrigin(origin)) |
- return; |
+ DCHECK(IsUsageCacheEnabledForOrigin(origin)); |
std::string host = net::GetHostOrSpecFromURL(origin); |
int64* usage = &cached_usage_by_host_[host][origin]; |