diff options
author | pastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-10 13:57:05 +0000 |
---|---|---|
committer | pastarmovj@chromium.org <pastarmovj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-10 13:57:05 +0000 |
commit | 2edc32ff69735ae01c8ab8d72f782d206af91c72 (patch) | |
tree | 8fb45b73223731935d8f1feb865ebfc91c24f59b /chrome/browser/appcache | |
parent | e6cc40238ca63abc7eb25fc7426cb4d796f48067 (diff) | |
download | chromium_src-2edc32ff69735ae01c8ab8d72f782d206af91c72.zip chromium_src-2edc32ff69735ae01c8ab8d72f782d206af91c72.tar.gz chromium_src-2edc32ff69735ae01c8ab8d72f782d206af91c72.tar.bz2 |
Refactored app cache clear on exit code to happen in the object owning the files.
In an effort to remove the static functions that used to be called from the
BrowserProcessImpl very late in the shutdown process and move the code to
immediately after the files get freed from their respective users. Which
will help to parallelize the shutdown sequence better and ensure files are
deleted when they are not used anymore.
BUG=65076
TEST=TBA
Review URL: http://codereview.chromium.org/6077005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70893 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/appcache')
-rw-r--r-- | chrome/browser/appcache/chrome_appcache_service.cc | 46 | ||||
-rw-r--r-- | chrome/browser/appcache/chrome_appcache_service.h | 11 | ||||
-rw-r--r-- | chrome/browser/appcache/chrome_appcache_service_unittest.cc | 99 |
3 files changed, 145 insertions, 11 deletions
diff --git a/chrome/browser/appcache/chrome_appcache_service.cc b/chrome/browser/appcache/chrome_appcache_service.cc index c01b1d7..6c84999 100644 --- a/chrome/browser/appcache/chrome_appcache_service.cc +++ b/chrome/browser/appcache/chrome_appcache_service.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -15,6 +15,20 @@ static bool has_initialized_thread_ids; +namespace { + +// Used to defer deleting of local storage until the destructor has finished. +void DeleteLocalStateOnIOThread(FilePath cache_path) { + // Post the actual deletion to the DB thread to ensure it happens after the + // database file has been closed. + BrowserThread::PostTask( + BrowserThread::DB, FROM_HERE, + NewRunnableFunction<bool(*)(const FilePath&, bool), FilePath, bool>( + &file_util::Delete, cache_path, true)); +} + +} // namespace + // ---------------------------------------------------------------------------- ChromeAppCacheService::ChromeAppCacheService() { @@ -22,7 +36,8 @@ ChromeAppCacheService::ChromeAppCacheService() { void ChromeAppCacheService::InitializeOnIOThread( const FilePath& profile_path, bool is_incognito, - scoped_refptr<HostContentSettingsMap> content_settings_map) { + scoped_refptr<HostContentSettingsMap> content_settings_map, + bool clear_local_state_on_exit) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (!has_initialized_thread_ids) { @@ -33,16 +48,24 @@ void ChromeAppCacheService::InitializeOnIOThread( host_contents_settings_map_ = content_settings_map; registrar_.Add( this, NotificationType::PURGE_MEMORY, NotificationService::AllSources()); + SetClearLocalStateOnExit(clear_local_state_on_exit); + if (!is_incognito) + cache_path_ = profile_path.Append(chrome::kAppCacheDirname); // Init our base class. - Initialize( - is_incognito ? FilePath() : profile_path.Append(chrome::kAppCacheDirname), - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)); + Initialize(cache_path_, + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)); set_appcache_policy(this); } ChromeAppCacheService::~ChromeAppCacheService() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (clear_local_state_on_exit_ && !cache_path_.empty()) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableFunction(DeleteLocalStateOnIOThread, cache_path_)); + } } void ChromeAppCacheService::SetOriginQuotaInMemory( @@ -58,9 +81,16 @@ void ChromeAppCacheService::ResetOriginQuotaInMemory(const GURL& origin) { storage()->ResetOriginQuotaInMemory(origin); } -// static -void ChromeAppCacheService::ClearLocalState(const FilePath& profile_path) { - file_util::Delete(profile_path.Append(chrome::kAppCacheDirname), true); +void ChromeAppCacheService::SetClearLocalStateOnExit(bool clear_local_state) { + if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(this, + &ChromeAppCacheService::SetClearLocalStateOnExit, + clear_local_state)); + return; + } + clear_local_state_on_exit_ = clear_local_state; } bool ChromeAppCacheService::CanLoadAppCache(const GURL& manifest_url) { diff --git a/chrome/browser/appcache/chrome_appcache_service.h b/chrome/browser/appcache/chrome_appcache_service.h index dbc0616..0b43759 100644 --- a/chrome/browser/appcache/chrome_appcache_service.h +++ b/chrome/browser/appcache/chrome_appcache_service.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -35,14 +35,15 @@ class ChromeAppCacheService void InitializeOnIOThread( const FilePath& profile_path, bool is_incognito, - scoped_refptr<HostContentSettingsMap> content_settings_map); + scoped_refptr<HostContentSettingsMap> content_settings_map, + bool clear_local_state_on_exit); // Helpers used by the extension service to grant and revoke // unlimited storage to app extensions. void SetOriginQuotaInMemory(const GURL& origin, int64 quota); void ResetOriginQuotaInMemory(const GURL& origin); - static void ClearLocalState(const FilePath& profile_path); + void SetClearLocalStateOnExit(bool clear_local_state); private: friend class BrowserThread; @@ -62,6 +63,10 @@ class ChromeAppCacheService scoped_refptr<HostContentSettingsMap> host_contents_settings_map_; NotificationRegistrar registrar_; + bool clear_local_state_on_exit_; + FilePath cache_path_; + + DISALLOW_COPY_AND_ASSIGN(ChromeAppCacheService); }; #endif // CHROME_BROWSER_APPCACHE_CHROME_APPCACHE_SERVICE_H_ diff --git a/chrome/browser/appcache/chrome_appcache_service_unittest.cc b/chrome/browser/appcache/chrome_appcache_service_unittest.cc new file mode 100644 index 0000000..0cb5090 --- /dev/null +++ b/chrome/browser/appcache/chrome_appcache_service_unittest.cc @@ -0,0 +1,99 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/file_util.h" +#include "base/message_loop.h" +#include "base/ref_counted.h" +#include "base/scoped_temp_dir.h" +#include "chrome/browser/appcache/chrome_appcache_service.h" +#include "chrome/browser/browser_thread.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/test/thread_test_helper.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/appcache/appcache_storage_impl.h" + +namespace appcache { + +class ChromeAppCacheServiceTest : public testing::Test { + public: + ChromeAppCacheServiceTest() + : message_loop_(MessageLoop::TYPE_IO), + db_thread_(BrowserThread::DB, &message_loop_), + file_thread_(BrowserThread::FILE, &message_loop_), + cache_thread_(BrowserThread::CACHE, &message_loop_), + io_thread_(BrowserThread::IO, &message_loop_) { + } + + protected: + MessageLoop message_loop_; + ScopedTempDir temp_dir_; + + private: + BrowserThread db_thread_; + BrowserThread file_thread_; + BrowserThread cache_thread_; + BrowserThread io_thread_; +}; + +TEST_F(ChromeAppCacheServiceTest, KeepOnDestruction) { + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + FilePath appcache_path = temp_dir_.path().Append(chrome::kAppCacheDirname); + scoped_refptr<ChromeAppCacheService> appcache_service = + new ChromeAppCacheService; + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(appcache_service.get(), + &ChromeAppCacheService::InitializeOnIOThread, + temp_dir_.path(), false, + scoped_refptr<HostContentSettingsMap>(NULL), + false)); + // Make the steps needed to initialize the storage of AppCache data. + message_loop_.RunAllPending(); + appcache::AppCacheStorageImpl* storage = + static_cast<appcache::AppCacheStorageImpl*>(appcache_service->storage()); + ASSERT_TRUE(storage->database_->db_connection()); + ASSERT_EQ(1, storage->NewCacheId()); + storage->disk_cache(); + message_loop_.RunAllPending(); + + ASSERT_TRUE(file_util::PathExists(appcache_path)); + ASSERT_TRUE(file_util::PathExists(appcache_path.AppendASCII("Index"))); + + appcache_service = NULL; + message_loop_.RunAllPending(); + + ASSERT_TRUE(file_util::PathExists(appcache_path)); +} + +TEST_F(ChromeAppCacheServiceTest, RemoveOnDestruction) { + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + FilePath appcache_path = temp_dir_.path().Append(chrome::kAppCacheDirname); + scoped_refptr<ChromeAppCacheService> appcache_service = + new ChromeAppCacheService; + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(appcache_service.get(), + &ChromeAppCacheService::InitializeOnIOThread, + temp_dir_.path(), false, + scoped_refptr<HostContentSettingsMap>(NULL), + true)); + // Make the steps needed to initialize the storage of AppCache data. + message_loop_.RunAllPending(); + appcache::AppCacheStorageImpl* storage = + static_cast<appcache::AppCacheStorageImpl*>(appcache_service->storage()); + ASSERT_TRUE(storage->database_->db_connection()); + ASSERT_EQ(1, storage->NewCacheId()); + storage->disk_cache(); + message_loop_.RunAllPending(); + + ASSERT_TRUE(file_util::PathExists(appcache_path)); + ASSERT_TRUE(file_util::PathExists(appcache_path.AppendASCII("Index"))); + + appcache_service = NULL; + message_loop_.RunAllPending(); + + ASSERT_FALSE(file_util::PathExists(appcache_path)); +} + +} // namespace appcache |