summaryrefslogtreecommitdiffstats
path: root/webkit/quota
diff options
context:
space:
mode:
authortzik@google.com <tzik@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-11 11:01:17 +0000
committertzik@google.com <tzik@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-11 11:01:17 +0000
commitd6fcf7e808e51f8f865423b7cd935c9e707debbc (patch)
treede7d7522adef0e4d55ded5c7c8b2a86c7f38b8aa /webkit/quota
parent845b43a8e2652e74447fedd648216769e3d1e566 (diff)
downloadchromium_src-d6fcf7e808e51f8f865423b7cd935c9e707debbc.zip
chromium_src-d6fcf7e808e51f8f865423b7cd935c9e707debbc.tar.gz
chromium_src-d6fcf7e808e51f8f865423b7cd935c9e707debbc.tar.bz2
Added {Get,Set}PersistentHostQuota
BUG=61676 TEST='QuotaManagerTests.*' Review URL: http://codereview.chromium.org/6904042 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84963 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/quota')
-rw-r--r--webkit/quota/mock_storage_client.cc30
-rw-r--r--webkit/quota/mock_storage_client.h8
-rw-r--r--webkit/quota/quota_manager.cc300
-rw-r--r--webkit/quota/quota_manager.h21
-rw-r--r--webkit/quota/quota_manager_unittest.cc379
-rw-r--r--webkit/quota/quota_types.h61
6 files changed, 718 insertions, 81 deletions
diff --git a/webkit/quota/mock_storage_client.cc b/webkit/quota/mock_storage_client.cc
index ee1a0b1..74f5e28 100644
--- a/webkit/quota/mock_storage_client.cc
+++ b/webkit/quota/mock_storage_client.cc
@@ -19,6 +19,8 @@ namespace quota {
namespace {
+using std::make_pair;
+
class MockStorageClientIDSequencer {
public:
static MockStorageClientIDSequencer* GetInstance() {
@@ -54,17 +56,21 @@ MockStorageClient::~MockStorageClient() {
void MockStorageClient::AddMockOriginData(
const GURL& origin_url, StorageType type, int64 size) {
- origin_data_.insert(std::make_pair(origin_url, MockOriginData(type, size)));
+ origin_data_[make_pair(origin_url, type)] = size;
}
void MockStorageClient::ModifyMockOriginDataSize(
const GURL& origin_url, StorageType type, int64 delta) {
- std::map<GURL, MockOriginData>::iterator find = origin_data_.find(origin_url);
- if (find == origin_data_.end() || find->second.type != type) {
+ OriginDataMap::iterator find = origin_data_.find(make_pair(origin_url, type));
+ if (find == origin_data_.end()) {
DCHECK(delta >= 0);
AddMockOriginData(origin_url, type, delta);
return;
}
+ find->second += delta;
+ DCHECK(find->second >= 0);
+
+ // TODO(tzik): Check quota to prevent usage exceed
quota_manager_proxy_->NotifyStorageModified(id(), origin_url, type, delta);
}
@@ -109,11 +115,11 @@ void MockStorageClient::RunGetOriginUsage(
const GURL& origin_url, StorageType type, GetUsageCallback* callback_ptr) {
usage_callbacks_.erase(callback_ptr);
scoped_ptr<GetUsageCallback> callback(callback_ptr);
- std::map<GURL, MockOriginData>::iterator find = origin_data_.find(origin_url);
+ OriginDataMap::iterator find = origin_data_.find(make_pair(origin_url, type));
if (find == origin_data_.end()) {
callback->Run(0);
} else {
- callback->Run(find->second.usage);
+ callback->Run(find->second);
}
}
@@ -122,10 +128,10 @@ void MockStorageClient::RunGetOriginsForType(
scoped_ptr<GetOriginsCallback> callback(callback_ptr);
origins_callbacks_.erase(callback_ptr);
std::set<GURL> origins;
- for (std::map<GURL, MockOriginData>::iterator iter = origin_data_.begin();
+ for (OriginDataMap::iterator iter = origin_data_.begin();
iter != origin_data_.end(); ++iter) {
- if (type == iter->second.type)
- origins.insert(iter->first);
+ if (type == iter->first.second)
+ origins.insert(iter->first.first);
}
callback->Run(origins);
}
@@ -136,11 +142,11 @@ void MockStorageClient::RunGetOriginsForHost(
scoped_ptr<GetOriginsCallback> callback(callback_ptr);
origins_callbacks_.erase(callback_ptr);
std::set<GURL> origins;
- for (std::map<GURL, MockOriginData>::iterator iter = origin_data_.begin();
+ for (OriginDataMap::iterator iter = origin_data_.begin();
iter != origin_data_.end(); ++iter) {
- std::string host_or_spec = net::GetHostOrSpecFromURL(iter->first);
- if (type == iter->second.type && host == host_or_spec)
- origins.insert(iter->first);
+ std::string host_or_spec = net::GetHostOrSpecFromURL(iter->first.first);
+ if (type == iter->first.second && host == host_or_spec)
+ origins.insert(iter->first.first);
}
callback->Run(origins);
}
diff --git a/webkit/quota/mock_storage_client.h b/webkit/quota/mock_storage_client.h
index ac2545b..e1ad61e 100644
--- a/webkit/quota/mock_storage_client.h
+++ b/webkit/quota/mock_storage_client.h
@@ -51,12 +51,8 @@ class MockStorageClient : public QuotaClient {
scoped_refptr<QuotaManagerProxy> quota_manager_proxy_;
const ID id_;
- struct MockOriginData {
- MockOriginData(StorageType type, int64 usage) : type(type), usage(usage) { }
- StorageType type;
- int64 usage;
- };
- std::map<GURL, MockOriginData> origin_data_;
+ typedef std::map<std::pair<GURL, StorageType>, int64> OriginDataMap;
+ OriginDataMap origin_data_;
std::set<GetUsageCallback*> usage_callbacks_;
std::set<GetOriginsCallback*> origins_callbacks_;
diff --git a/webkit/quota/quota_manager.cc b/webkit/quota/quota_manager.cc
index 16b44ef..2e2db35 100644
--- a/webkit/quota/quota_manager.cc
+++ b/webkit/quota/quota_manager.cc
@@ -84,12 +84,16 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask {
CheckCompleted();
}
- void DidGetGlobalQuota(int64 quota) {
+ void DidGetGlobalQuota(QuotaStatusCode status, int64 quota) {
+ quota_status_ = status;
quota_ = quota;
CheckCompleted();
}
- void DidGetHostQuota(const std::string& host_unused, int64 quota) {
+ void DidGetHostQuota(QuotaStatusCode status,
+ const std::string& host_unused,
+ int64 quota) {
+ quota_status_ = status;
quota_ = quota;
CheckCompleted();
}
@@ -105,6 +109,7 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask {
quota_(-1),
global_usage_(-1),
host_usage_(-1),
+ quota_status_(kQuotaStatusUnknown),
callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}
virtual ~UsageAndQuotaDispatcherTask() {
@@ -136,6 +141,7 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask {
int64 quota() const { return quota_; }
int64 global_usage() const { return global_usage_; }
int64 host_usage() const { return host_usage_; }
+ QuotaStatusCode status() const { return quota_status_; }
UsageCallback* NewGlobalUsageCallback() {
return callback_factory_.NewCallback(
@@ -182,6 +188,7 @@ class QuotaManager::UsageAndQuotaDispatcherTask : public QuotaTask {
int64 quota_;
int64 global_usage_;
int64 host_usage_;
+ QuotaStatusCode quota_status_;
CallbackList callbacks_;
ScopedCallbackFactory<UsageAndQuotaDispatcherTask> callback_factory_;
@@ -213,7 +220,7 @@ class QuotaManager::UsageAndQuotaDispatcherTaskForTemporary
// to return {usage, quota - nonevictable_usage} once eviction is
// supported.
int64 other_usage = global_usage() - host_usage();
- callback->Run(kQuotaStatusOk, host_usage(), quota() - other_usage);
+ callback->Run(status(), host_usage(), quota() - other_usage);
}
};
@@ -237,7 +244,7 @@ class QuotaManager::UsageAndQuotaDispatcherTaskForPersistent
}
virtual void DispatchCallback(GetUsageAndQuotaCallback* callback) OVERRIDE {
- callback->Run(kQuotaStatusOk, host_usage(), quota());
+ callback->Run(status(), host_usage(), quota());
}
};
@@ -292,10 +299,10 @@ class QuotaManager::InitializeTask : public QuotaThreadTask {
virtual void Completed() OVERRIDE {
DCHECK(manager_);
- if (manager_->temporary_global_quota_ < 0)
- manager_->DidGetTemporaryGlobalQuota(temporary_storage_quota_);
manager_->db_initialized_ = !db_disabled_;
manager_->db_disabled_ = db_disabled_;
+ if (manager_->temporary_global_quota_ < 0)
+ manager_->DidGetTemporaryGlobalQuota(temporary_storage_quota_);
}
private:
@@ -306,36 +313,122 @@ class QuotaManager::InitializeTask : public QuotaThreadTask {
bool db_disabled_;
};
-class QuotaManager::TemporaryGlobalQuotaUpdateTask : public QuotaThreadTask {
+class QuotaManager::TemporaryGlobalQuotaUpdateTask
+ : public QuotaThreadTask {
public:
TemporaryGlobalQuotaUpdateTask(
QuotaManager* manager,
QuotaDatabase* database,
scoped_refptr<base::MessageLoopProxy> db_message_loop,
- int64 new_quota)
+ int64 new_quota,
+ QuotaCallback* callback)
: QuotaThreadTask(manager, db_message_loop),
manager_(manager),
database_(database),
new_quota_(new_quota),
+ callback_(callback),
db_disabled_(false) {
DCHECK(database_);
+ DCHECK(new_quota >=0);
}
protected:
virtual void RunOnTargetThread() OVERRIDE {
- if (!database_->SetGlobalQuota(kStorageTypeTemporary, new_quota_))
+ if (!database_->SetGlobalQuota(kStorageTypeTemporary, new_quota_)) {
db_disabled_ = true;
+ new_quota_ = 0;
+ }
}
virtual void Completed() OVERRIDE {
DCHECK(manager_);
manager_->db_disabled_ = db_disabled_;
+ callback_->Run(db_disabled_ ? kQuotaErrorInvalidAccess : kQuotaStatusOk,
+ new_quota_);
+ }
+
+ private:
+ QuotaManager* manager_;
+ QuotaDatabase* database_;
+ int64 new_quota_;
+ scoped_ptr<QuotaCallback> callback_;
+ bool db_disabled_;
+};
+
+class QuotaManager::PersistentHostQuotaQueryTask : public QuotaThreadTask {
+ public:
+ PersistentHostQuotaQueryTask(
+ QuotaManager* manager,
+ QuotaDatabase* database,
+ scoped_refptr<base::MessageLoopProxy> db_message_loop,
+ const std::string& host,
+ HostQuotaCallback* callback)
+ : QuotaThreadTask(manager, db_message_loop),
+ manager_(manager),
+ database_(database),
+ host_(host),
+ quota_(-1),
+ callback_(callback) {
+ DCHECK(manager_);
+ DCHECK(database_);
+ DCHECK(!host_.empty());
+ }
+ protected:
+ virtual void RunOnTargetThread() OVERRIDE {
+ if (!database_->GetHostQuota(host_, kStorageTypePersistent, &quota_))
+ quota_ = 0;
+ }
+ virtual void Completed() OVERRIDE {
+ callback_->Run(kQuotaStatusOk, host_, quota_);
+ }
+ private:
+ QuotaManager* manager_;
+ QuotaDatabase* database_;
+ std::string host_;
+ int64 quota_;
+ scoped_ptr<HostQuotaCallback> callback_;
+};
+
+class QuotaManager::PersistentHostQuotaUpdateTask : public QuotaThreadTask {
+ public:
+ PersistentHostQuotaUpdateTask(
+ QuotaManager* manager,
+ QuotaDatabase* database,
+ scoped_refptr<base::MessageLoopProxy> db_message_loop,
+ const std::string& host,
+ int new_quota,
+ HostQuotaCallback* callback)
+ : QuotaThreadTask(manager, db_message_loop),
+ manager_(manager),
+ database_(database),
+ host_(host),
+ new_quota_(new_quota),
+ callback_(callback),
+ db_disabled_(false) {
+ DCHECK(manager_);
+ DCHECK(database_);
+ DCHECK(!host_.empty());
+ DCHECK(new_quota_ >= 0);
+ }
+ protected:
+ virtual void RunOnTargetThread() OVERRIDE {
+ if (!database_->SetHostQuota(host_, kStorageTypePersistent, new_quota_)) {
+ db_disabled_ = true;
+ new_quota_ = 0;
+ }
}
+ virtual void Completed() OVERRIDE {
+ manager_->db_disabled_ = db_disabled_;
+ callback_->Run(db_disabled_ ? kQuotaErrorInvalidAccess : kQuotaStatusOk,
+ host_, new_quota_);
+ }
private:
QuotaManager* manager_;
QuotaDatabase* database_;
+ std::string host_;
int64 new_quota_;
+ scoped_ptr<HostQuotaCallback> callback_;
bool db_disabled_;
};
@@ -411,7 +504,7 @@ void QuotaManager::GetTemporaryGlobalQuota(QuotaCallback* callback) {
if (temporary_global_quota_ >= 0) {
// TODO(kinuko): The in-memory quota value should be periodically
// updated not to exceed the current available space in the hard drive.
- callback->Run(temporary_global_quota_);
+ callback->Run(kQuotaStatusOk, temporary_global_quota_);
delete callback;
return;
}
@@ -419,39 +512,56 @@ void QuotaManager::GetTemporaryGlobalQuota(QuotaCallback* callback) {
temporary_global_quota_callbacks_.Add(callback);
}
-void QuotaManager::SetTemporaryGlobalQuota(int64 new_quota) {
+void QuotaManager::SetTemporaryGlobalQuota(int64 new_quota,
+ QuotaCallback* callback) {
LazyInitialize();
- DCHECK(new_quota >= 0);
+ if (new_quota < 0) {
+ callback->Run(kQuotaErrorInvalidModification, -1);
+ delete callback;
+ return;
+ }
+
DidGetTemporaryGlobalQuota(new_quota);
if (!db_disabled_) {
scoped_refptr<TemporaryGlobalQuotaUpdateTask> task(
new TemporaryGlobalQuotaUpdateTask(
- this, database_.get(), db_thread_, new_quota));
+ this, database_.get(), db_thread_, new_quota, callback));
task->Start();
+ } else {
+ callback->Run(kQuotaErrorInvalidAccess, -1);
+ delete callback;
}
}
void QuotaManager::GetPersistentHostQuota(const std::string& host,
HostQuotaCallback* callback) {
LazyInitialize();
- std::map<std::string, int64>::iterator found =
- persistent_host_quota_.find(host);
- if (found != persistent_host_quota_.end()) {
- callback->Run(host, found->second);
- delete callback;
- return;
- }
- if (persistent_host_quota_callbacks_.Add(host, callback)) {
- // This is the first call for this host.
- // TODO(kinuko): Dispatch a task to get the host quota for the host
- // once QuotaDatabase is updated to accept hosts instead of origins.
- }
+
+ scoped_refptr<PersistentHostQuotaQueryTask> task(
+ new PersistentHostQuotaQueryTask(
+ this, database_.get(), db_thread_, host, callback));
+ task->Start();
}
void QuotaManager::SetPersistentHostQuota(const std::string& host,
- int64 new_quota) {
+ int64 new_quota,
+ HostQuotaCallback* callback) {
LazyInitialize();
- // TODO(kinuko): Implement once QuotaDatabase is updated.
+ if (new_quota < 0) {
+ callback->Run(kQuotaErrorInvalidModification, host, -1);
+ delete callback;
+ return;
+ }
+
+ if (!db_disabled_) {
+ scoped_refptr<PersistentHostQuotaUpdateTask> task(
+ new PersistentHostQuotaUpdateTask(
+ this, database_.get(), db_thread_, host, new_quota, callback));
+ task->Start();
+ } else {
+ callback->Run(kQuotaErrorInvalidAccess, host, -1);
+ delete callback;
+ }
}
void QuotaManager::LazyInitialize() {
@@ -505,14 +615,9 @@ UsageTracker* QuotaManager::GetUsageTracker(StorageType type) const {
void QuotaManager::DidGetTemporaryGlobalQuota(int64 quota) {
temporary_global_quota_ = quota;
- temporary_global_quota_callbacks_.Run(quota);
-}
-
-void QuotaManager::DidGetPersistentHostQuota(const std::string& host,
- int64 quota) {
- DCHECK(persistent_host_quota_.find(host) == persistent_host_quota_.end());
- persistent_host_quota_[host] = quota;
- persistent_host_quota_callbacks_.Run(host, host, quota);
+ temporary_global_quota_callbacks_.Run(
+ db_disabled_ ? kQuotaErrorInvalidAccess : kQuotaStatusOk,
+ quota);
}
void QuotaManager::DeleteOnCorrectThread() const {
@@ -523,6 +628,131 @@ void QuotaManager::DeleteOnCorrectThread() const {
delete this;
}
+class QuotaManager::GlobalUsageQueryTask : public QuotaTask {
+ public:
+ GlobalUsageQueryTask(QuotaManager* manager,
+ StorageType type,
+ UsageCallback* callback)
+ : QuotaTask(manager),
+ manager_(manager),
+ callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ type_(type),
+ usage_(0),
+ callback_(callback) {}
+
+ protected:
+ virtual void Run() OVERRIDE {
+ UsageTracker* tracker = NULL;
+
+ switch (type_) {
+ case kStorageTypeTemporary:
+ tracker = manager_->temporary_usage_tracker_.get();
+ break;
+ case kStorageTypePersistent:
+ tracker = manager_->persistent_usage_tracker_.get();
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ DCHECK(tracker);
+ tracker->GetGlobalUsage(
+ callback_factory_.NewCallback(
+ &GlobalUsageQueryTask::DidGetGlobalUsage));
+ }
+
+ virtual void Aborted() OVERRIDE {
+ delete this;
+ }
+
+ virtual void Completed() OVERRIDE {
+ callback_->Run(usage_);
+ delete this;
+ }
+ private:
+ QuotaManager* manager_;
+ ScopedCallbackFactory<GlobalUsageQueryTask> callback_factory_;
+ StorageType type_;
+ int64 usage_;
+ UsageCallback* callback_;
+
+ void DidGetGlobalUsage(int64 usage) {
+ usage_ += usage;
+ CallCompleted();
+ }
+};
+
+class QuotaManager::HostUsageQueryTask : public QuotaTask {
+ public:
+ HostUsageQueryTask(QuotaManager* manager,
+ const std::string& host,
+ StorageType type,
+ HostUsageCallback* callback)
+ : QuotaTask(manager),
+ manager_(manager),
+ callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ usage_(0),
+ host_(host),
+ type_(type),
+ callback_(callback) {}
+
+ protected:
+ virtual void Run() OVERRIDE {
+ UsageTracker* tracker = NULL;
+ switch (type_) {
+ case kStorageTypeTemporary:
+ tracker = manager_->temporary_usage_tracker_.get();
+ break;
+ case kStorageTypePersistent:
+ tracker = manager_->persistent_usage_tracker_.get();
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ DCHECK(tracker);
+ tracker->GetHostUsage(
+ host_,
+ callback_factory_.NewCallback(
+ &HostUsageQueryTask::DidGetHostUsage));
+ }
+
+ virtual void Aborted() OVERRIDE {
+ delete this;
+ }
+
+ virtual void Completed() OVERRIDE {
+ callback_->Run(host_, usage_);
+ delete this;
+ }
+ private:
+ QuotaManager* manager_;
+ ScopedCallbackFactory<HostUsageQueryTask> callback_factory_;
+ int task_count_;
+ int64 usage_;
+ std::string host_;
+ StorageType type_;
+ HostUsageCallback* callback_;
+
+ void DidGetHostUsage(const std::string&, int64 usage) {
+ usage_ = usage;
+ CallCompleted();
+ }
+};
+
+void QuotaManager::GetGlobalUsage(StorageType type, UsageCallback* callback){
+ LazyInitialize();
+ QuotaTask* task = new GlobalUsageQueryTask(this, type, callback);
+ task->Start();
+}
+
+void QuotaManager::GetHostUsage(const std::string& host, StorageType type,
+ HostUsageCallback* callback) {
+ LazyInitialize();
+ QuotaTask* task = new HostUsageQueryTask(this, host, type, callback);
+ task->Start();
+}
+
// QuotaManagerProxy ----------------------------------------------------------
void QuotaManagerProxy::GetUsageAndQuota(
diff --git a/webkit/quota/quota_manager.h b/webkit/quota/quota_manager.h
index 16c0588..d54336f 100644
--- a/webkit/quota/quota_manager.h
+++ b/webkit/quota/quota_manager.h
@@ -67,14 +67,16 @@ class QuotaManager : public QuotaTaskObserver,
// Called by UI and internal modules.
void GetTemporaryGlobalQuota(QuotaCallback* callback);
- void SetTemporaryGlobalQuota(int64 new_quota);
+ void SetTemporaryGlobalQuota(int64 new_quota, QuotaCallback* callback);
void GetPersistentHostQuota(const std::string& host,
HostQuotaCallback* callback);
- void SetPersistentHostQuota(const std::string& host, int64 new_quota);
+ void SetPersistentHostQuota(const std::string& host,
+ int64 new_quota,
+ HostQuotaCallback* callback);
- // TODO(kinuko): Add more APIs for UI:
- // - Get temporary global/per-host usage
- // - Get persistent global/per-host usage
+ void GetGlobalUsage(StorageType type, UsageCallback* callback);
+ void GetHostUsage(const std::string& host, StorageType type,
+ HostUsageCallback* callback);
const static int64 kTemporaryStorageQuotaDefaultSize;
const static int64 kTemporaryStorageQuotaMaxSize;
@@ -85,11 +87,16 @@ class QuotaManager : public QuotaTaskObserver,
private:
class InitializeTask;
class TemporaryGlobalQuotaUpdateTask;
+ class PersistentHostQuotaUpdateTask;
+ class PersistentHostQuotaQueryTask;
class UsageAndQuotaDispatcherTask;
class UsageAndQuotaDispatcherTaskForTemporary;
class UsageAndQuotaDispatcherTaskForPersistent;
+ class GlobalUsageQueryTask;
+ class HostUsageQueryTask;
+
typedef std::pair<std::string, StorageType> HostAndType;
typedef std::map<HostAndType, UsageAndQuotaDispatcherTask*>
UsageAndQuotaDispatcherTaskMap;
@@ -119,7 +126,6 @@ class QuotaManager : public QuotaTaskObserver,
UsageTracker* GetUsageTracker(StorageType type) const;
void DidGetTemporaryGlobalQuota(int64 quota);
- void DidGetPersistentHostQuota(const std::string& host, int64 quota);
void DeleteOnCorrectThread() const;
@@ -143,9 +149,6 @@ class QuotaManager : public QuotaTaskObserver,
int64 temporary_global_quota_;
QuotaCallbackQueue temporary_global_quota_callbacks_;
- std::map<std::string, int64> persistent_host_quota_;
- HostQuotaCallbackMap persistent_host_quota_callbacks_;
-
DISALLOW_COPY_AND_ASSIGN(QuotaManager);
};
diff --git a/webkit/quota/quota_manager_unittest.cc b/webkit/quota/quota_manager_unittest.cc
index eb0af8f..d931cab 100644
--- a/webkit/quota/quota_manager_unittest.cc
+++ b/webkit/quota/quota_manager_unittest.cc
@@ -72,7 +72,7 @@ class QuotaManagerTest : public testing::Test {
}
void GetUsageAndQuota(const GURL& origin, StorageType type) {
- status_ = kQuotaStatusUnknown;
+ quota_status_ = kQuotaStatusUnknown;
usage_ = -1;
quota_ = -1;
quota_manager_->GetUsageAndQuota(origin, type,
@@ -80,6 +80,52 @@ class QuotaManagerTest : public testing::Test {
&QuotaManagerTest::DidGetUsageAndQuota));
}
+ void GetTemporaryGlobalQuota() {
+ quota_status_ = kQuotaStatusUnknown;
+ quota_ = -1;
+ quota_manager_->GetTemporaryGlobalQuota(
+ callback_factory_.NewCallback(
+ &QuotaManagerTest::DidGetQuota));
+ }
+
+ void SetTemporaryGlobalQuota(int64 new_quota) {
+ quota_status_ = kQuotaStatusUnknown;
+ quota_ = -1;
+ quota_manager_->SetTemporaryGlobalQuota(new_quota,
+ callback_factory_.NewCallback(
+ &QuotaManagerTest::DidGetQuota));
+ }
+
+ void GetPersistentHostQuota(const std::string& host) {
+ quota_status_ = kQuotaStatusUnknown;
+ quota_ = -1;
+ quota_manager_->GetPersistentHostQuota(host,
+ callback_factory_.NewCallback(
+ &QuotaManagerTest::DidGetHostQuota));
+ }
+
+ void SetPersistentHostQuota(const std::string& host, int64 new_quota) {
+ quota_status_ = kQuotaStatusUnknown;
+ quota_ = -1;
+ quota_manager_->SetPersistentHostQuota(host, new_quota,
+ callback_factory_.NewCallback(
+ &QuotaManagerTest::DidGetHostQuota));
+ }
+
+ void GetGlobalUsage(StorageType type) {
+ usage_ = -1;
+ quota_manager_->GetGlobalUsage(type,
+ callback_factory_.NewCallback(
+ &QuotaManagerTest::DidGetGlobalUsage));
+ }
+
+ void GetHostUsage(const std::string& host, StorageType type) {
+ usage_ = -1;
+ quota_manager_->GetHostUsage(host, type,
+ callback_factory_.NewCallback(
+ &QuotaManagerTest::DidGetHostUsage));
+ }
+
void RunAdditionalUsageAndQuotaTask(const GURL& origin, StorageType type) {
quota_manager_->GetUsageAndQuota(origin, type,
callback_factory_.NewCallback(
@@ -87,11 +133,31 @@ class QuotaManagerTest : public testing::Test {
}
void DidGetUsageAndQuota(QuotaStatusCode status, int64 usage, int64 quota) {
- status_ = status;
+ quota_status_ = status;
usage_ = usage;
quota_ = quota;
}
+ void DidGetQuota(QuotaStatusCode status, int64 quota) {
+ quota_status_ = status;
+ quota_ = quota;
+ }
+
+ void DidGetHostQuota(QuotaStatusCode status,
+ const std::string& host, int64 quota) {
+ quota_status_ = status;
+ host_ = host;
+ quota_ = quota;
+ }
+
+ void DidGetGlobalUsage(int64 usage) {
+ usage_ = usage;
+ }
+
+ void DidGetHostUsage(const std::string&, int64 usage) {
+ usage_ = usage;
+ }
+
void set_additional_callback_count(int c) { additional_callback_count_ = c; }
int additional_callback_count() const { return additional_callback_count_; }
void DidGetUsageAndQuotaAdditional(
@@ -104,7 +170,7 @@ class QuotaManagerTest : public testing::Test {
quota_manager_ = quota_manager;
}
- QuotaStatusCode status() const { return status_; }
+ QuotaStatusCode status() const { return quota_status_; }
int64 usage() const { return usage_; }
int64 quota() const { return quota_; }
@@ -114,7 +180,8 @@ class QuotaManagerTest : public testing::Test {
scoped_refptr<QuotaManager> quota_manager_;
- QuotaStatusCode status_;
+ QuotaStatusCode quota_status_;
+ std::string host_;
int64 usage_;
int64 quota_;
@@ -123,19 +190,25 @@ class QuotaManagerTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(QuotaManagerTest);
};
-TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_Simple) {
+TEST_F(QuotaManagerTest, GetUsageAndQuota_Simple) {
const static MockOriginData kData[] = {
{ "http://foo.com/", kStorageTypeTemporary, 10 },
{ "http://foo.com/", kStorageTypePersistent, 80 },
};
RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(80, usage());
+ EXPECT_EQ(0, quota());
+
GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypeTemporary);
MessageLoop::current()->RunAllPending();
EXPECT_EQ(kQuotaStatusOk, status());
EXPECT_EQ(10, usage());
- EXPECT_GT(quota(), 0);
- EXPECT_LE(quota(), QuotaManager::kTemporaryStorageQuotaMaxSize);
+ EXPECT_LE(0, quota());
+ EXPECT_GE(QuotaManager::kTemporaryStorageQuotaMaxSize, quota());
int64 quota_returned_for_foo = quota();
GetUsageAndQuota(GURL("http://bar.com/"), kStorageTypeTemporary);
@@ -145,19 +218,61 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_Simple) {
EXPECT_EQ(quota_returned_for_foo - 10, quota());
}
-TEST_F(QuotaManagerTest, GetTemporaryUsage_NoClient) {
+TEST_F(QuotaManagerTest, GetUsage_NoClient) {
GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypeTemporary);
MessageLoop::current()->RunAllPending();
EXPECT_EQ(kQuotaStatusOk, status());
EXPECT_EQ(0, usage());
+
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(0, usage());
+
+ GetHostUsage("foo.com", kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(0, usage());
+
+ GetHostUsage("foo.com", kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(0, usage());
+
+ GetGlobalUsage(kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(0, usage());
+
+ GetGlobalUsage(kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(0, usage());
}
-TEST_F(QuotaManagerTest, GetTemporaryUsage_EmptyClient) {
+TEST_F(QuotaManagerTest, GetUsage_EmptyClient) {
RegisterClient(CreateClient(NULL, 0));
GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypeTemporary);
MessageLoop::current()->RunAllPending();
EXPECT_EQ(kQuotaStatusOk, status());
EXPECT_EQ(0, usage());
+
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(0, usage());
+
+ GetHostUsage("foo.com", kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(0, usage());
+
+ GetHostUsage("foo.com", kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(0, usage());
+
+ GetGlobalUsage(kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(0, usage());
+
+ GetGlobalUsage(kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(0, usage());
}
TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_MultiOrigins) {
@@ -172,7 +287,10 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_MultiOrigins) {
RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
// This time explicitly sets a temporary global quota.
- quota_manager()->SetTemporaryGlobalQuota(100);
+ SetTemporaryGlobalQuota(100);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(100, quota());
GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypeTemporary);
MessageLoop::current()->RunAllPending();
@@ -189,10 +307,11 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_MultiOrigins) {
EXPECT_EQ(100 - (10 + 20 + 30), quota());
}
-TEST_F(QuotaManagerTest, GetTemporaryUsage_MultipleClients) {
+TEST_F(QuotaManagerTest, GetUsage_MultipleClients) {
const static MockOriginData kData1[] = {
{ "http://foo.com/", kStorageTypeTemporary, 10 },
{ "http://bar.com/", kStorageTypeTemporary, 20 },
+ { "http://bar.com/", kStorageTypePersistent, 50 },
};
const static MockOriginData kData2[] = {
{ "https://foo.com/", kStorageTypeTemporary, 30 },
@@ -205,6 +324,21 @@ TEST_F(QuotaManagerTest, GetTemporaryUsage_MultipleClients) {
MessageLoop::current()->RunAllPending();
EXPECT_EQ(kQuotaStatusOk, status());
EXPECT_EQ(10 + 30, usage());
+
+ GetUsageAndQuota(GURL("http://bar.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(50, usage());
+
+ GetGlobalUsage(kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(10 + 20 + 30, usage());
+
+ GetGlobalUsage(kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(40 + 50, usage());
}
TEST_F(QuotaManagerTest, GetTemporaryUsage_WithModify) {
@@ -246,7 +380,7 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_WithAdditionalTasks) {
{ "http://foo.com/", kStorageTypePersistent, 40 },
};
RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
- quota_manager()->SetTemporaryGlobalQuota(100);
+ SetTemporaryGlobalQuota(100);
GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypeTemporary);
GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypeTemporary);
@@ -277,7 +411,7 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_NukeManager) {
{ "http://foo.com/", kStorageTypePersistent, 40 },
};
RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
- quota_manager()->SetTemporaryGlobalQuota(100);
+ SetTemporaryGlobalQuota(100);
set_additional_callback_count(0);
GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypeTemporary);
@@ -292,4 +426,223 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_NukeManager) {
EXPECT_EQ(kQuotaErrorAbort, status());
}
+TEST_F(QuotaManagerTest, GetAndSetPerststentHostQuota) {
+ RegisterClient(CreateClient(NULL, 0));
+
+ GetPersistentHostQuota("foo.com");
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(0, quota());
+
+ SetPersistentHostQuota("foo.com", 100);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(100, quota());
+
+ GetPersistentHostQuota("foo.com");
+ SetPersistentHostQuota("foo.com", 200);
+ GetPersistentHostQuota("foo.com");
+ SetPersistentHostQuota("foo.com", 300);
+ GetPersistentHostQuota("foo.com");
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(300, quota());
+}
+
+TEST_F(QuotaManagerTest, GetAndSetPersistentUsageAndQuota) {
+ RegisterClient(CreateClient(NULL, 0));
+
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(0, usage());
+ EXPECT_EQ(0, quota());
+
+ SetPersistentHostQuota("foo.com",100);
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(0, usage());
+ EXPECT_EQ(100, quota());
+}
+
+TEST_F(QuotaManagerTest, GetPersistentUsageAndQuota_MultiOrigins) {
+ const static MockOriginData kData[] = {
+ { "http://foo.com/", kStorageTypePersistent, 10 },
+ { "http://foo.com:8080/", kStorageTypePersistent, 20 },
+ { "https://foo.com/", kStorageTypePersistent, 13 },
+ { "https://foo.com:8081/", kStorageTypePersistent, 19 },
+ { "http://bar.com/", kStorageTypePersistent, 5 },
+ { "https://bar.com/", kStorageTypePersistent, 7 },
+ { "http://baz.com/", kStorageTypePersistent, 30 },
+ { "http://foo.com/", kStorageTypeTemporary, 40 },
+ };
+ RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
+
+ SetPersistentHostQuota("foo.com", 100);
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(10 + 20 + 13 + 19, usage());
+ EXPECT_EQ(100, quota());
+}
+
+TEST_F(QuotaManagerTest, GetPersistentUsage_WithModify) {
+ const static MockOriginData kData[] = {
+ { "http://foo.com/", kStorageTypePersistent, 10 },
+ { "http://foo.com:1/", kStorageTypePersistent, 20 },
+ };
+ MockStorageClient* client = CreateClient(kData, ARRAYSIZE_UNSAFE(kData));
+ RegisterClient(client);
+
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(10 + 20, usage());
+
+ client->ModifyMockOriginDataSize(
+ GURL("http://foo.com/"), kStorageTypePersistent, 20);
+ client->ModifyMockOriginDataSize(
+ GURL("http://foo.com:1/"), kStorageTypePersistent, -5);
+ client->ModifyMockOriginDataSize(
+ GURL("http://bar.com/"), kStorageTypePersistent, 33);
+
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(10 + 20 + 20 - 5, usage());
+
+ GetUsageAndQuota(GURL("http://bar.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(33, usage());
+}
+
+TEST_F(QuotaManagerTest, GetPersistentUsageAndQuota_WithAdditionalTasks) {
+ const static MockOriginData kData[] = {
+ { "http://foo.com/", kStorageTypePersistent, 10 },
+ { "http://foo.com:8080/", kStorageTypePersistent, 20 },
+ { "http://bar.com/", kStorageTypePersistent, 13 },
+ { "http://foo.com/", kStorageTypeTemporary, 40 },
+ };
+ RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
+ SetPersistentHostQuota("foo.com",100);
+
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(10 + 20, usage());
+ EXPECT_EQ(100, quota());
+
+ set_additional_callback_count(0);
+ RunAdditionalUsageAndQuotaTask(GURL("http://foo.com/"),
+ kStorageTypePersistent);
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ RunAdditionalUsageAndQuotaTask(GURL("http://bar.com/"),
+ kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaStatusOk, status());
+ EXPECT_EQ(10 + 20, usage());
+ EXPECT_EQ(2, additional_callback_count());
+}
+
+TEST_F(QuotaManagerTest, GetPersistentUsageAndQuota_NukeManager) {
+ const static MockOriginData kData[] = {
+ { "http://foo.com/", kStorageTypePersistent, 10 },
+ { "http://foo.com:8080/", kStorageTypePersistent, 20 },
+ { "http://bar.com/", kStorageTypePersistent, 13 },
+ { "http://foo.com/", kStorageTypeTemporary, 40 },
+ };
+ RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
+ SetPersistentHostQuota("foo.com", 100);
+
+ set_additional_callback_count(0);
+ GetUsageAndQuota(GURL("http://foo.com/"), kStorageTypePersistent);
+ RunAdditionalUsageAndQuotaTask(GURL("http://foo.com/"),
+ kStorageTypePersistent);
+ RunAdditionalUsageAndQuotaTask(GURL("http://bar.com/"),
+ kStorageTypePersistent);
+
+ // Nuke before waiting for callbacks.
+ set_quota_manager(NULL);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(kQuotaErrorAbort, status());
+}
+
+TEST_F(QuotaManagerTest, GetUsage_Simple) {
+ const static MockOriginData kData[] = {
+ { "http://foo.com/", kStorageTypePersistent, 1 },
+ { "http://foo.com:1/", kStorageTypePersistent, 20 },
+ { "http://bar.com/", kStorageTypeTemporary, 300 },
+ { "https://buz.com/", kStorageTypeTemporary, 4000 },
+ { "http://buz.com/", kStorageTypeTemporary, 50000 },
+ { "http://bar.com:1/", kStorageTypePersistent, 600000 },
+ { "http://foo.com/", kStorageTypeTemporary, 7000000 },
+ };
+ RegisterClient(CreateClient(kData, ARRAYSIZE_UNSAFE(kData)));
+
+ GetGlobalUsage(kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(usage(), 1 + 20 + 600000);
+
+ GetGlobalUsage(kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(usage(), 300 + 4000 + 50000 + 7000000);
+
+ GetHostUsage("foo.com", kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(usage(), 1 + 20);
+
+ GetHostUsage("buz.com", kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(usage(), 4000 + 50000);
+}
+
+TEST_F(QuotaManagerTest, GetUsage_WithModification) {
+ const static MockOriginData kData[] = {
+ { "http://foo.com/", kStorageTypePersistent, 1 },
+ { "http://foo.com:1/", kStorageTypePersistent, 20 },
+ { "http://bar.com/", kStorageTypeTemporary, 300 },
+ { "https://buz.com/", kStorageTypeTemporary, 4000 },
+ { "http://buz.com/", kStorageTypeTemporary, 50000 },
+ { "http://bar.com:1/", kStorageTypePersistent, 600000 },
+ { "http://foo.com/", kStorageTypeTemporary, 7000000 },
+ };
+
+ MockStorageClient* client = CreateClient(kData, ARRAYSIZE_UNSAFE(kData));
+ RegisterClient(client);
+
+ GetGlobalUsage(kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(usage(), 1 + 20 + 600000);
+
+ client->ModifyMockOriginDataSize(
+ GURL("http://foo.com/"), kStorageTypePersistent, 80000000);
+
+ GetGlobalUsage(kStorageTypePersistent);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(usage(), 1 + 20 + 600000 + 80000000);
+
+ GetGlobalUsage(kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(usage(), 300 + 4000 + 50000 + 7000000);
+
+ client->ModifyMockOriginDataSize(
+ GURL("http://foo.com/"), kStorageTypeTemporary, 1);
+
+ GetGlobalUsage(kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(usage(), 300 + 4000 + 50000 + 7000000 + 1);
+
+ GetHostUsage("buz.com", kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(usage(), 4000 + 50000);
+
+ client->ModifyMockOriginDataSize(
+ GURL("http://buz.com/"), kStorageTypeTemporary, 900000000);
+
+ GetHostUsage("buz.com", kStorageTypeTemporary);
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(usage(), 4000 + 50000 + 900000000);
+}
+
} // namespace quota
diff --git a/webkit/quota/quota_types.h b/webkit/quota/quota_types.h
index 2d42440..f4d7d26 100644
--- a/webkit/quota/quota_types.h
+++ b/webkit/quota/quota_types.h
@@ -22,19 +22,26 @@ enum StorageType {
kStorageTypeUnknown,
};
+// TODO(tzik): Add assertions to
+// content/browser/renderer_host/quota_dispatcher_host.cc
+// ref) third_party/WebKit/Source/WebCore/dom/ExceptionCode.h,
enum QuotaStatusCode {
kQuotaStatusOk = 0,
- kQuotaErrorNotSupported = 9,
- kQuotaErrorAbort = 20,
+ kQuotaErrorNotSupported = 9, // NOT_SUPPORTED_ERR
+ kQuotaErrorInvalidModification = 13, // INVALID_MODIFICATION_ERR
+ kQuotaErrorInvalidAccess = 15, // INVALID_ACCESS_ERR
+ kQuotaErrorAbort = 20, // ABORT_ERR
kQuotaStatusUnknown = -1,
};
// Common callback types that are used throughout in the quota module.
typedef Callback1<int64>::Type UsageCallback;
-typedef Callback1<int64>::Type QuotaCallback;
+typedef Callback2<QuotaStatusCode,
+ int64>::Type QuotaCallback;
typedef Callback2<const std::string& /* host */,
int64>::Type HostUsageCallback;
-typedef Callback2<const std::string& /* host */,
+typedef Callback3<QuotaStatusCode,
+ const std::string& /* host */,
int64>::Type HostQuotaCallback;
// Simple template wrapper for a callback queue.
@@ -93,8 +100,24 @@ class CallbackQueue2 : public CallbackQueueBase<CallbackType2> {
}
};
+template <typename CallbackType3, typename A1, typename A2, typename A3>
+class CallbackQueue3 : public CallbackQueueBase<CallbackType3> {
+ public:
+ typedef typename CallbackQueueBase<CallbackType3>::Queue Queue;
+ // Runs the callbacks added to the queue and clears the queue.
+ void Run(A1 arg1, A2 arg2, A3 arg3) {
+ for (typename Queue::iterator iter = this->callbacks_.begin();
+ iter != this->callbacks_.end(); ++iter) {
+ (*iter)->Run(arg1, arg2, arg3);
+ delete *iter;
+ }
+ this->callbacks_.clear();
+ }
+};
+
typedef CallbackQueue1<UsageCallback*, int64> UsageCallbackQueue;
-typedef CallbackQueue1<QuotaCallback*, int64> QuotaCallbackQueue;
+typedef CallbackQueue2<QuotaCallback*,
+ QuotaStatusCode, int64> QuotaCallbackQueue;
template <typename CallbackType, typename CallbackQueueType, typename KEY>
class CallbackQueueMapBase {
@@ -165,9 +188,35 @@ class CallbackQueueMap2
}
};
+template <typename CallbackType3, typename KEY,
+ typename ARG1, typename ARG2, typename ARG3>
+class CallbackQueueMap3
+ : public CallbackQueueMapBase<CallbackType3,
+ CallbackQueue3<CallbackType3,
+ ARG1, ARG2, ARG3>,
+ KEY> {
+ public:
+ typedef typename CallbackQueueMapBase<
+ CallbackType3,
+ CallbackQueue3<CallbackType3, ARG1, ARG2, ARG3>,
+ KEY>::iterator iterator;
+ typedef CallbackQueue3<CallbackType3, ARG1, ARG2, ARG3> Queue;
+
+ // Runs the callbacks added for the given |key| and clears the key
+ // from the map.
+ void Run(const KEY& key, ARG1 arg1, ARG2 arg2, ARG3 arg3) {
+ if (!this->HasCallbacks(key))
+ return;
+ Queue& queue = this->callback_map_[key];
+ queue.Run(arg1, arg2, arg3);
+ this->callback_map_.erase(key);
+ }
+};
+
typedef CallbackQueueMap2<HostUsageCallback*, std::string,
const std::string&, int64> HostUsageCallbackMap;
-typedef CallbackQueueMap2<HostUsageCallback*, std::string,
+typedef CallbackQueueMap3<HostQuotaCallback*, std::string,
+ QuotaStatusCode,
const std::string&, int64> HostQuotaCallbackMap;
} // namespace quota