summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authormichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-12 18:29:43 +0000
committermichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-12 18:29:43 +0000
commit0de9b67aa1b649f0df8d5a5910b2e26b3f42aa38 (patch)
tree91c016fb7c1a80ae9bd0051a74399e50586bf478 /webkit
parent79e2336c1782fff5147a447495a20729007935c2 (diff)
downloadchromium_src-0de9b67aa1b649f0df8d5a5910b2e26b3f42aa38.zip
chromium_src-0de9b67aa1b649f0df8d5a5910b2e26b3f42aa38.tar.gz
chromium_src-0de9b67aa1b649f0df8d5a5910b2e26b3f42aa38.tar.bz2
1) Declare three new proxayable QuotaManager methods:
// QuotaClients should call this method when storage is accessed. // Used to maintain LRU ordering. void NotifyStorageAccessed(client, origin, type); // Used to avoid evicting origins with open pages. // A call to NotifyOriginInUse must be balanced by a later call // to NotifyOriginNoLongerInUse. void NotifyOriginInUse(origin); void NotifyOriginNoLongerInUse(origin); Implemented the latter two along with an IsOriginInUse(origin) method. 2) Added a quota_manager() getter to the proxy interface for use only on the IO thread. 3) Removed GetUsageAndQuota from the proxy interface, since the impl does not support that. Changed the callsite for that to use proxy->quota_manager()->GetUsageAndQuota(). 4) Virtualized the proxy interface to make client testing easier. 5) Use raw MessageLoopProxy ptrs for ctor args instead of scoped_refptr<T> to avoid having to inlude as much. BUG=61676 TEST=added tests for OriginInUse bookeeping Review URL: http://codereview.chromium.org/6973017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85155 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/fileapi/file_system_operation.cc4
-rw-r--r--webkit/quota/quota_manager.cc73
-rw-r--r--webkit/quota/quota_manager.h67
-rw-r--r--webkit/quota/quota_manager_unittest.cc22
4 files changed, 134 insertions, 32 deletions
diff --git a/webkit/fileapi/file_system_operation.cc b/webkit/fileapi/file_system_operation.cc
index 1d6c5a6..ac9ef88 100644
--- a/webkit/fileapi/file_system_operation.cc
+++ b/webkit/fileapi/file_system_operation.cc
@@ -559,9 +559,9 @@ bool FileSystemOperation::GetUsageAndQuotaThenCallback(
quota::QuotaManager::GetUsageAndQuotaCallback* callback) {
quota::QuotaManagerProxy* quota_manager_proxy =
file_system_context()->quota_manager_proxy();
- if (quota_manager_proxy != NULL &&
+ if (quota_manager_proxy && quota_manager_proxy->quota_manager() &&
file_system_operation_context_.src_type() != kFileSystemTypeExternal) {
- quota_manager_proxy->GetUsageAndQuota(
+ quota_manager_proxy->quota_manager()->GetUsageAndQuota(
file_system_operation_context_.src_origin_url(),
FileSystemTypeToQuotaStorageType(
file_system_operation_context_.src_type()),
diff --git a/webkit/quota/quota_manager.cc b/webkit/quota/quota_manager.cc
index 16b44ef..060d379 100644
--- a/webkit/quota/quota_manager.cc
+++ b/webkit/quota/quota_manager.cc
@@ -341,8 +341,8 @@ class QuotaManager::TemporaryGlobalQuotaUpdateTask : public QuotaThreadTask {
QuotaManager::QuotaManager(bool is_incognito,
const FilePath& profile_path,
- scoped_refptr<base::MessageLoopProxy> io_thread,
- scoped_refptr<base::MessageLoopProxy> db_thread)
+ base::MessageLoopProxy* io_thread,
+ base::MessageLoopProxy* db_thread)
: is_incognito_(is_incognito),
profile_path_(profile_path),
proxy_(new QuotaManagerProxy(
@@ -482,6 +482,12 @@ void QuotaManager::RegisterClient(QuotaClient* client) {
clients_.push_back(client);
}
+void QuotaManager::NotifyStorageAccessed(
+ QuotaClient::ID client_id,
+ const GURL& origin, StorageType type) {
+ // TODO(michaeln): write me
+}
+
void QuotaManager::NotifyStorageModified(
QuotaClient::ID client_id,
const GURL& origin, StorageType type, int64 delta) {
@@ -491,6 +497,19 @@ void QuotaManager::NotifyStorageModified(
tracker->UpdateUsageCache(client_id, origin, delta);
}
+void QuotaManager::NotifyOriginInUse(const GURL& origin) {
+ DCHECK(io_thread_->BelongsToCurrentThread());
+ origins_in_use_[origin]++;
+}
+
+void QuotaManager::NotifyOriginNoLongerInUse(const GURL& origin) {
+ DCHECK(io_thread_->BelongsToCurrentThread());
+ DCHECK(IsOriginInUse(origin));
+ int& count = origins_in_use_[origin];
+ if (--count == 0)
+ origins_in_use_.erase(origin);
+}
+
UsageTracker* QuotaManager::GetUsageTracker(StorageType type) const {
switch (type) {
case kStorageTypeTemporary:
@@ -525,15 +544,6 @@ void QuotaManager::DeleteOnCorrectThread() const {
// QuotaManagerProxy ----------------------------------------------------------
-void QuotaManagerProxy::GetUsageAndQuota(
- const GURL& origin,
- StorageType type,
- QuotaManager::GetUsageAndQuotaCallback* callback) {
- DCHECK(io_thread_->BelongsToCurrentThread());
- if (manager_)
- manager_->GetUsageAndQuota(origin, type, callback);
-}
-
void QuotaManagerProxy::RegisterClient(QuotaClient* client) {
if (!io_thread_->BelongsToCurrentThread()) {
io_thread_->PostTask(FROM_HERE, NewRunnableMethod(
@@ -546,6 +556,20 @@ void QuotaManagerProxy::RegisterClient(QuotaClient* client) {
client->OnQuotaManagerDestroyed();
}
+void QuotaManagerProxy::NotifyStorageAccessed(
+ QuotaClient::ID client_id,
+ const GURL& origin,
+ StorageType type) {
+ if (!io_thread_->BelongsToCurrentThread()) {
+ io_thread_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &QuotaManagerProxy::NotifyStorageAccessed,
+ client_id, origin, type));
+ return;
+ }
+ if (manager_)
+ manager_->NotifyStorageAccessed(client_id, origin, type);
+}
+
void QuotaManagerProxy::NotifyStorageModified(
QuotaClient::ID client_id,
const GURL& origin,
@@ -561,6 +585,33 @@ void QuotaManagerProxy::NotifyStorageModified(
manager_->NotifyStorageModified(client_id, origin, type, delta);
}
+void QuotaManagerProxy::NotifyOriginInUse(
+ const GURL& origin) {
+ if (!io_thread_->BelongsToCurrentThread()) {
+ io_thread_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &QuotaManagerProxy::NotifyOriginInUse, origin));
+ return;
+ }
+ if (manager_)
+ manager_->NotifyOriginInUse(origin);
+}
+
+void QuotaManagerProxy::NotifyOriginNoLongerInUse(
+ const GURL& origin) {
+ if (!io_thread_->BelongsToCurrentThread()) {
+ io_thread_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &QuotaManagerProxy::NotifyOriginNoLongerInUse, origin));
+ return;
+ }
+ if (manager_)
+ manager_->NotifyOriginNoLongerInUse(origin);
+}
+
+QuotaManager* QuotaManagerProxy::quota_manager() const {
+ DCHECK(!io_thread_ || io_thread_->BelongsToCurrentThread());
+ return manager_;
+}
+
QuotaManagerProxy::QuotaManagerProxy(
QuotaManager* manager, base::MessageLoopProxy* io_thread)
: manager_(manager), io_thread_(io_thread) {
diff --git a/webkit/quota/quota_manager.h b/webkit/quota/quota_manager.h
index 16c0588..684d2b0 100644
--- a/webkit/quota/quota_manager.h
+++ b/webkit/quota/quota_manager.h
@@ -20,6 +20,9 @@
#include "webkit/quota/quota_task.h"
#include "webkit/quota/quota_types.h"
+namespace base {
+class MessageLoopProxy;
+}
class FilePath;
namespace quota {
@@ -45,8 +48,8 @@ class QuotaManager : public QuotaTaskObserver,
QuotaManager(bool is_incognito,
const FilePath& profile_path,
- scoped_refptr<base::MessageLoopProxy> io_thread,
- scoped_refptr<base::MessageLoopProxy> db_thread);
+ base::MessageLoopProxy* io_thread,
+ base::MessageLoopProxy* db_thread);
virtual ~QuotaManager();
@@ -65,6 +68,30 @@ class QuotaManager : public QuotaTaskObserver,
int64 requested_size,
RequestQuotaCallback* callback);
+ // Called by clients via proxy.
+ // QuotaClients should call this method when storage is accessed.
+ // Used to maintain LRU ordering.
+ void NotifyStorageAccessed(QuotaClient::ID client_id,
+ const GURL& origin,
+ StorageType typea);
+
+ // Called by clients via proxy.
+ // QuotaClients must call this method whenever they have made any
+ // modifications that change the amount of data stored in their storage.
+ void NotifyStorageModified(QuotaClient::ID client_id,
+ const GURL& origin,
+ StorageType type,
+ int64 delta);
+
+ // Used to avoid evicting origins with open pages.
+ // A call to NotifyOriginInUse must be balanced by a later call
+ // to NotifyOriginNoLongerInUse.
+ void NotifyOriginInUse(const GURL& origin);
+ void NotifyOriginNoLongerInUse(const GURL& origin);
+ bool IsOriginInUse(const GURL& origin) const {
+ return origins_in_use_.find(origin) != origins_in_use_.end();
+ }
+
// Called by UI and internal modules.
void GetTemporaryGlobalQuota(QuotaCallback* callback);
void SetTemporaryGlobalQuota(int64 new_quota);
@@ -108,14 +135,6 @@ class QuotaManager : public QuotaTaskObserver,
// The client must remain valid until OnQuotaManagerDestored is called.
void RegisterClient(QuotaClient* client);
- // Called by clients via proxy.
- // QuotaClients must call this method whenever they have made any
- // modifications that change the amount of data stored in their storage.
- void NotifyStorageModified(QuotaClient::ID client_id,
- const GURL& origin,
- StorageType type,
- int64 delta);
-
UsageTracker* GetUsageTracker(StorageType type) const;
void DidGetTemporaryGlobalQuota(int64 quota);
@@ -146,6 +165,9 @@ class QuotaManager : public QuotaTaskObserver,
std::map<std::string, int64> persistent_host_quota_;
HostQuotaCallbackMap persistent_host_quota_callbacks_;
+ // Map from origin to count.
+ std::map<GURL, int> origins_in_use_;
+
DISALLOW_COPY_AND_ASSIGN(QuotaManager);
};
@@ -159,15 +181,22 @@ struct QuotaManagerDeleter {
class QuotaManagerProxy
: public base::RefCountedThreadSafe<QuotaManagerProxy> {
public:
- void GetUsageAndQuota(const GURL& origin,
- StorageType type,
- QuotaManager::GetUsageAndQuotaCallback* callback);
- void RegisterClient(QuotaClient* client);
- void NotifyStorageModified(QuotaClient::ID client_id,
- const GURL& origin,
- StorageType type,
- int64 delta);
- private:
+ virtual void RegisterClient(QuotaClient* client);
+ virtual void NotifyStorageAccessed(QuotaClient::ID client_id,
+ const GURL& origin,
+ StorageType type);
+ virtual void NotifyStorageModified(QuotaClient::ID client_id,
+ const GURL& origin,
+ StorageType type,
+ int64 delta);
+ virtual void NotifyOriginInUse(const GURL& origin);
+ virtual void NotifyOriginNoLongerInUse(const GURL& origin);
+
+ // This method may only be called on the IO thread.
+ // It may return NULL if the manager has already been deleted.
+ QuotaManager* quota_manager() const;
+
+ protected:
friend class QuotaManager;
friend class base::RefCountedThreadSafe<QuotaManagerProxy>;
QuotaManagerProxy(QuotaManager* manager, base::MessageLoopProxy* io_thread);
diff --git a/webkit/quota/quota_manager_unittest.cc b/webkit/quota/quota_manager_unittest.cc
index eb0af8f..a590a68 100644
--- a/webkit/quota/quota_manager_unittest.cc
+++ b/webkit/quota/quota_manager_unittest.cc
@@ -292,4 +292,26 @@ TEST_F(QuotaManagerTest, GetTemporaryUsageAndQuota_NukeManager) {
EXPECT_EQ(kQuotaErrorAbort, status());
}
+TEST_F(QuotaManagerTest, OriginInUse) {
+ const GURL kFooOrigin("http://foo.com/");
+ const GURL kBarOrigin("http://bar.com/");
+
+ EXPECT_FALSE(quota_manager()->IsOriginInUse(kFooOrigin));
+ quota_manager()->NotifyOriginInUse(kFooOrigin); // count of 1
+ EXPECT_TRUE(quota_manager()->IsOriginInUse(kFooOrigin));
+ quota_manager()->NotifyOriginInUse(kFooOrigin); // count of 2
+ EXPECT_TRUE(quota_manager()->IsOriginInUse(kFooOrigin));
+ quota_manager()->NotifyOriginNoLongerInUse(kFooOrigin); // count of 1
+ EXPECT_TRUE(quota_manager()->IsOriginInUse(kFooOrigin));
+
+ EXPECT_FALSE(quota_manager()->IsOriginInUse(kBarOrigin));
+ quota_manager()->NotifyOriginInUse(kBarOrigin);
+ EXPECT_TRUE(quota_manager()->IsOriginInUse(kBarOrigin));
+ quota_manager()->NotifyOriginNoLongerInUse(kBarOrigin);
+ EXPECT_FALSE(quota_manager()->IsOriginInUse(kBarOrigin));
+
+ quota_manager()->NotifyOriginNoLongerInUse(kFooOrigin);
+ EXPECT_FALSE(quota_manager()->IsOriginInUse(kFooOrigin));
+}
+
} // namespace quota