diff options
Diffstat (limited to 'webkit/quota')
-rw-r--r-- | webkit/quota/quota_manager.cc | 73 | ||||
-rw-r--r-- | webkit/quota/quota_manager.h | 67 | ||||
-rw-r--r-- | webkit/quota/quota_manager_unittest.cc | 22 |
3 files changed, 132 insertions, 30 deletions
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 |