OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/quota/quota_manager.h" | 5 #include "webkit/quota/quota_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <deque> | 8 #include <deque> |
9 #include <set> | 9 #include <set> |
10 | 10 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 QuotaManager* manager, | 113 QuotaManager* manager, |
114 const std::string& host, | 114 const std::string& host, |
115 StorageType type) | 115 StorageType type) |
116 : QuotaTask(manager), | 116 : QuotaTask(manager), |
117 host_(host), | 117 host_(host), |
118 type_(type), | 118 type_(type), |
119 quota_(-1), | 119 quota_(-1), |
120 global_usage_(-1), | 120 global_usage_(-1), |
121 host_usage_(-1), | 121 host_usage_(-1), |
122 quota_status_(kQuotaStatusUnknown), | 122 quota_status_(kQuotaStatusUnknown), |
| 123 waiting_callbacks_(1), |
123 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {} | 124 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {} |
124 | 125 |
125 virtual ~UsageAndQuotaDispatcherTask() { | 126 virtual ~UsageAndQuotaDispatcherTask() { |
126 STLDeleteContainerPointers(callbacks_.begin(), callbacks_.end()); | 127 STLDeleteContainerPointers(callbacks_.begin(), callbacks_.end()); |
127 } | 128 } |
128 | 129 |
129 virtual bool IsCompleted() const = 0; | 130 // Subclasses must implement them. |
| 131 virtual void RunBody() = 0; |
| 132 virtual void DispatchCallback(GetUsageAndQuotaCallback* callback) = 0; |
130 | 133 |
131 virtual void DispatchCallback(GetUsageAndQuotaCallback* callback) = 0; | 134 virtual void Run() OVERRIDE { |
| 135 RunBody(); |
| 136 // We initialize waiting_callbacks to 1 so that we won't run |
| 137 // the completion callback until here even some of the callbacks |
| 138 // are dispatched synchronously. |
| 139 CheckCompleted(); |
| 140 } |
132 | 141 |
133 virtual void Aborted() OVERRIDE { | 142 virtual void Aborted() OVERRIDE { |
134 for (CallbackList::iterator iter = callbacks_.begin(); | 143 for (CallbackList::iterator iter = callbacks_.begin(); |
135 iter != callbacks_.end(); | 144 iter != callbacks_.end(); |
136 ++iter) { | 145 ++iter) { |
137 (*iter)->Run(kQuotaErrorAbort, 0, 0); | 146 (*iter)->Run(kQuotaErrorAbort, 0, 0); |
138 delete *iter; | 147 delete *iter; |
139 } | 148 } |
140 callbacks_.clear(); | 149 callbacks_.clear(); |
141 DeleteSoon(); | 150 DeleteSoon(); |
142 } | 151 } |
143 | 152 |
144 virtual void Completed() OVERRIDE { | 153 virtual void Completed() OVERRIDE { |
145 DeleteSoon(); | 154 DeleteSoon(); |
146 } | 155 } |
| 156 |
147 QuotaManager* manager() const { | 157 QuotaManager* manager() const { |
148 return static_cast<QuotaManager*>(observer()); | 158 return static_cast<QuotaManager*>(observer()); |
149 } | 159 } |
150 | 160 |
151 std::string host() const { return host_; } | 161 std::string host() const { return host_; } |
152 StorageType type() const { return type_; } | 162 StorageType type() const { return type_; } |
153 int64 quota() const { return quota_; } | 163 int64 quota() const { return quota_; } |
154 int64 global_usage() const { return global_usage_; } | 164 int64 global_usage() const { return global_usage_; } |
155 int64 host_usage() const { return host_usage_; } | 165 int64 host_usage() const { return host_usage_; } |
156 QuotaStatusCode status() const { return quota_status_; } | 166 QuotaStatusCode quota_status() const { return quota_status_; } |
157 | 167 |
158 UsageCallback* NewGlobalUsageCallback() { | 168 // Subclasses must call following methods to create a new 'waitable' |
| 169 // callback, which decrements waiting_callbacks when it is called. |
| 170 UsageCallback* NewWaitableGlobalUsageCallback() { |
| 171 ++waiting_callbacks_; |
159 return callback_factory_.NewCallback( | 172 return callback_factory_.NewCallback( |
160 &UsageAndQuotaDispatcherTask::DidGetGlobalUsage); | 173 &UsageAndQuotaDispatcherTask::DidGetGlobalUsage); |
161 } | 174 } |
162 | 175 HostUsageCallback* NewWaitableHostUsageCallback() { |
163 HostUsageCallback* NewHostUsageCallback() { | 176 ++waiting_callbacks_; |
164 return callback_factory_.NewCallback( | 177 return callback_factory_.NewCallback( |
165 &UsageAndQuotaDispatcherTask::DidGetHostUsage); | 178 &UsageAndQuotaDispatcherTask::DidGetHostUsage); |
166 } | 179 } |
167 | 180 QuotaCallback* NewWaitableGlobalQuotaCallback() { |
168 QuotaCallback* NewGlobalQuotaCallback() { | 181 ++waiting_callbacks_; |
169 return callback_factory_.NewCallback( | 182 return callback_factory_.NewCallback( |
170 &UsageAndQuotaDispatcherTask::DidGetGlobalQuota); | 183 &UsageAndQuotaDispatcherTask::DidGetGlobalQuota); |
171 } | 184 } |
172 | 185 HostQuotaCallback* NewWaitableHostQuotaCallback() { |
173 HostQuotaCallback* NewHostQuotaCallback() { | 186 ++waiting_callbacks_; |
174 return callback_factory_.NewCallback( | 187 return callback_factory_.NewCallback( |
175 &UsageAndQuotaDispatcherTask::DidGetHostQuota); | 188 &UsageAndQuotaDispatcherTask::DidGetHostQuota); |
176 } | 189 } |
177 | 190 |
178 private: | 191 private: |
179 void CheckCompleted() { | 192 void CheckCompleted() { |
180 if (IsCompleted()) { | 193 if (--waiting_callbacks_ <= 0) { |
181 // Dispatches callbacks. | 194 // Dispatches callbacks. |
182 for (CallbackList::iterator iter = callbacks_.begin(); | 195 for (CallbackList::iterator iter = callbacks_.begin(); |
183 iter != callbacks_.end(); | 196 iter != callbacks_.end(); |
184 ++iter) { | 197 ++iter) { |
185 DispatchCallback(*iter); | 198 DispatchCallback(*iter); |
186 delete *iter; | 199 delete *iter; |
187 } | 200 } |
188 callbacks_.clear(); | 201 callbacks_.clear(); |
189 UsageAndQuotaDispatcherTaskMap& dispatcher_map = | 202 UsageAndQuotaDispatcherTaskMap& dispatcher_map = |
190 manager()->usage_and_quota_dispatchers_; | 203 manager()->usage_and_quota_dispatchers_; |
191 DCHECK(dispatcher_map.find(std::make_pair(host_, type_)) != | 204 DCHECK(dispatcher_map.find(std::make_pair(host_, type_)) != |
192 dispatcher_map.end()); | 205 dispatcher_map.end()); |
193 dispatcher_map.erase(std::make_pair(host_, type_)); | 206 dispatcher_map.erase(std::make_pair(host_, type_)); |
194 CallCompleted(); | 207 CallCompleted(); |
195 } | 208 } |
196 } | 209 } |
197 | 210 |
198 const std::string host_; | 211 const std::string host_; |
199 const StorageType type_; | 212 const StorageType type_; |
200 int64 quota_; | 213 int64 quota_; |
201 int64 global_usage_; | 214 int64 global_usage_; |
202 int64 host_usage_; | 215 int64 host_usage_; |
203 QuotaStatusCode quota_status_; | 216 QuotaStatusCode quota_status_; |
204 CallbackList callbacks_; | 217 CallbackList callbacks_; |
| 218 int waiting_callbacks_; |
205 ScopedCallbackFactory<UsageAndQuotaDispatcherTask> callback_factory_; | 219 ScopedCallbackFactory<UsageAndQuotaDispatcherTask> callback_factory_; |
206 | 220 |
207 DISALLOW_COPY_AND_ASSIGN(UsageAndQuotaDispatcherTask); | 221 DISALLOW_COPY_AND_ASSIGN(UsageAndQuotaDispatcherTask); |
208 }; | 222 }; |
209 | 223 |
210 class QuotaManager::UsageAndQuotaDispatcherTaskForTemporary | 224 class QuotaManager::UsageAndQuotaDispatcherTaskForTemporary |
211 : public QuotaManager::UsageAndQuotaDispatcherTask { | 225 : public QuotaManager::UsageAndQuotaDispatcherTask { |
212 public: | 226 public: |
213 UsageAndQuotaDispatcherTaskForTemporary( | 227 UsageAndQuotaDispatcherTaskForTemporary( |
214 QuotaManager* manager, const std::string host) | 228 QuotaManager* manager, const std::string host) |
215 : UsageAndQuotaDispatcherTask(manager, host, kStorageTypeTemporary) {} | 229 : UsageAndQuotaDispatcherTask(manager, host, kStorageTypeTemporary) {} |
216 | 230 |
217 protected: | 231 protected: |
218 virtual void Run() OVERRIDE { | 232 virtual void RunBody() OVERRIDE { |
219 manager()->temporary_usage_tracker_->GetGlobalUsage( | 233 manager()->temporary_usage_tracker_->GetGlobalUsage( |
220 NewGlobalUsageCallback()); | 234 NewWaitableGlobalUsageCallback()); |
221 manager()->temporary_usage_tracker_->GetHostUsage( | 235 manager()->temporary_usage_tracker_->GetHostUsage( |
222 host(), NewHostUsageCallback()); | 236 host(), NewWaitableHostUsageCallback()); |
223 manager()->GetTemporaryGlobalQuota(NewGlobalQuotaCallback()); | 237 manager()->GetTemporaryGlobalQuota(NewWaitableGlobalQuotaCallback()); |
224 } | |
225 | |
226 virtual bool IsCompleted() const OVERRIDE { | |
227 return (quota() >= 0 && global_usage() >= 0 && host_usage() >= 0); | |
228 } | 238 } |
229 | 239 |
230 virtual void DispatchCallback(GetUsageAndQuotaCallback* callback) OVERRIDE { | 240 virtual void DispatchCallback(GetUsageAndQuotaCallback* callback) OVERRIDE { |
231 // TODO(kinuko): For now it returns pessimistic quota. Change this | 241 // TODO(kinuko): For now it returns pessimistic quota. Change this |
232 // to return {usage, quota - nonevictable_usage} once eviction is | 242 // to return {usage, quota - nonevictable_usage} once eviction is |
233 // supported. | 243 // supported. |
234 int64 other_usage = global_usage() - host_usage(); | 244 int64 other_usage = global_usage() - host_usage(); |
235 callback->Run(status(), host_usage(), quota() - other_usage); | 245 callback->Run(quota_status(), host_usage(), quota() - other_usage); |
236 } | 246 } |
237 }; | 247 }; |
238 | 248 |
239 class QuotaManager::UsageAndQuotaDispatcherTaskForPersistent | 249 class QuotaManager::UsageAndQuotaDispatcherTaskForPersistent |
240 : public QuotaManager::UsageAndQuotaDispatcherTask { | 250 : public QuotaManager::UsageAndQuotaDispatcherTask { |
241 public: | 251 public: |
242 UsageAndQuotaDispatcherTaskForPersistent( | 252 UsageAndQuotaDispatcherTaskForPersistent( |
243 QuotaManager* manager, const std::string host) | 253 QuotaManager* manager, const std::string host) |
244 : UsageAndQuotaDispatcherTask(manager, host, kStorageTypePersistent) {} | 254 : UsageAndQuotaDispatcherTask(manager, host, kStorageTypePersistent) {} |
245 | 255 |
246 protected: | 256 protected: |
247 virtual void Run() OVERRIDE { | 257 virtual void RunBody() OVERRIDE { |
248 manager()->persistent_usage_tracker_->GetHostUsage( | 258 manager()->persistent_usage_tracker_->GetHostUsage( |
249 host(), NewHostUsageCallback()); | 259 host(), NewWaitableHostUsageCallback()); |
250 manager()->GetPersistentHostQuota( | 260 manager()->GetPersistentHostQuota( |
251 host(), NewHostQuotaCallback()); | 261 host(), NewWaitableHostQuotaCallback()); |
252 } | |
253 | |
254 virtual bool IsCompleted() const OVERRIDE { | |
255 return (quota() >= 0 && host_usage() >= 0); | |
256 } | 262 } |
257 | 263 |
258 virtual void DispatchCallback(GetUsageAndQuotaCallback* callback) OVERRIDE { | 264 virtual void DispatchCallback(GetUsageAndQuotaCallback* callback) OVERRIDE { |
259 callback->Run(status(), host_usage(), quota()); | 265 callback->Run(quota_status(), host_usage(), quota()); |
260 } | 266 } |
261 }; | 267 }; |
262 | 268 |
263 // static | 269 // static |
264 QuotaManager::UsageAndQuotaDispatcherTask* | 270 QuotaManager::UsageAndQuotaDispatcherTask* |
265 QuotaManager::UsageAndQuotaDispatcherTask::Create( | 271 QuotaManager::UsageAndQuotaDispatcherTask::Create( |
266 QuotaManager* manager, const std::string& host, StorageType type) { | 272 QuotaManager* manager, const std::string& host, StorageType type) { |
267 switch (type) { | 273 switch (type) { |
268 case kStorageTypeTemporary: | 274 case kStorageTypeTemporary: |
269 return new UsageAndQuotaDispatcherTaskForTemporary( | 275 return new UsageAndQuotaDispatcherTaskForTemporary( |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 | 1087 |
1082 QuotaManagerProxy::QuotaManagerProxy( | 1088 QuotaManagerProxy::QuotaManagerProxy( |
1083 QuotaManager* manager, base::MessageLoopProxy* io_thread) | 1089 QuotaManager* manager, base::MessageLoopProxy* io_thread) |
1084 : manager_(manager), io_thread_(io_thread) { | 1090 : manager_(manager), io_thread_(io_thread) { |
1085 } | 1091 } |
1086 | 1092 |
1087 QuotaManagerProxy::~QuotaManagerProxy() { | 1093 QuotaManagerProxy::~QuotaManagerProxy() { |
1088 } | 1094 } |
1089 | 1095 |
1090 } // namespace quota | 1096 } // namespace quota |
OLD | NEW |