Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(912)

Unified Diff: webkit/database/database_tracker.cc

Issue 7234014: Move code to clear web databases on shutdown to the database tracker (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: updates Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/database/database_tracker.h ('k') | webkit/database/database_tracker_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/database/database_tracker.cc
diff --git a/webkit/database/database_tracker.cc b/webkit/database/database_tracker.cc
index 7497c3814c7262279eeac8a242b42b1c921505d1..d01acda0c37780b2ed98e87cdd4b3400630fecc0 100644
--- a/webkit/database/database_tracker.cc
+++ b/webkit/database/database_tracker.cc
@@ -15,6 +15,7 @@
#include "base/basictypes.h"
#include "base/file_util.h"
#include "base/message_loop_proxy.h"
+#include "base/platform_file.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "net/base/net_errors.h"
@@ -47,7 +48,11 @@ const FilePath::CharType kTrackerDatabaseFileName[] =
FILE_PATH_LITERAL("Databases.db");
static const int kCurrentVersion = 2;
static const int kCompatibleVersion = 1;
-static const char* kExtensionOriginIdentifierPrefix = "chrome-extension_";
+
+const FilePath::CharType kTemporaryDirectoryPrefix[] =
+ FILE_PATH_LITERAL("DeleteMe");
+const FilePath::CharType kTemporaryDirectoryPattern[] =
+ FILE_PATH_LITERAL("DeleteMe*");
OriginInfo::OriginInfo()
: total_size_(0) {}
@@ -87,11 +92,13 @@ OriginInfo::OriginInfo(const string16& origin, int64 total_size)
DatabaseTracker::DatabaseTracker(
const FilePath& profile_path,
bool is_incognito,
+ bool clear_local_state_on_exit,
quota::SpecialStoragePolicy* special_storage_policy,
quota::QuotaManagerProxy* quota_manager_proxy,
base::MessageLoopProxy* db_tracker_thread)
: is_initialized_(false),
is_incognito_(is_incognito),
+ clear_local_state_on_exit_(clear_local_state_on_exit),
shutting_down_(false),
profile_path_(profile_path),
db_dir_(is_incognito_ ?
@@ -102,6 +109,7 @@ DatabaseTracker::DatabaseTracker(
meta_table_(NULL),
special_storage_policy_(special_storage_policy),
quota_manager_proxy_(quota_manager_proxy),
+ db_tracker_thread_(db_tracker_thread),
incognito_origin_directories_generator_(0) {
if (quota_manager_proxy) {
quota_manager_proxy->RegisterClient(
@@ -119,7 +127,7 @@ void DatabaseTracker::DatabaseOpened(const string16& origin_identifier,
const string16& database_description,
int64 estimated_size,
int64* database_size) {
- if (!LazyInit()) {
+ if (shutting_down_ || !LazyInit()) {
*database_size = 0;
return;
}
@@ -363,17 +371,18 @@ bool DatabaseTracker::DeleteClosedDatabase(const string16& origin_identifier,
if (databases_table_->GetAllDatabaseDetailsForOrigin(
origin_identifier, &details) && details.empty()) {
// Try to delete the origin in case this was the last database.
- DeleteOrigin(origin_identifier);
+ DeleteOrigin(origin_identifier, false);
}
return true;
}
-bool DatabaseTracker::DeleteOrigin(const string16& origin_identifier) {
+bool DatabaseTracker::DeleteOrigin(const string16& origin_identifier,
+ bool force) {
if (!LazyInit())
return false;
// Check if any database in this origin is opened by any renderer.
- if (database_connections_.IsOriginUsed(origin_identifier))
+ if (database_connections_.IsOriginUsed(origin_identifier) && !force)
return false;
int64 deleted_size = 0;
@@ -383,14 +392,28 @@ bool DatabaseTracker::DeleteOrigin(const string16& origin_identifier) {
deleted_size = origin_info->TotalSize();
}
- // We need to invalidate the cached record whether file_util::Delete()
- // succeeds or not, because even if it fails, it might still delete some
- // DB files on the hard drive.
origins_info_map_.erase(origin_identifier);
FilePath origin_dir = db_dir_.Append(FilePath::FromWStringHack(
UTF16ToWide(origin_identifier)));
- if (!file_util::Delete(origin_dir, true))
- return false;
+
+ // Create a temporary directory to move possibly still existing databases to,
+ // as we can't delete the origin directory on windows if it contains opened
+ // files.
+ FilePath new_origin_dir;
+ file_util::CreateTemporaryDirInDir(db_dir_,
+ kTemporaryDirectoryPrefix,
+ &new_origin_dir);
+ file_util::FileEnumerator databases(
+ origin_dir,
+ false,
+ file_util::FileEnumerator::FILES);
+ for (FilePath database = databases.Next(); !database.empty();
+ database = databases.Next()) {
+ FilePath new_file = new_origin_dir.Append(database.BaseName());
+ file_util::Move(database, new_file);
+ }
+ file_util::Delete(origin_dir, true);
+ file_util::Delete(new_origin_dir, true); // might fail on windows.
databases_table_->DeleteOrigin(origin_identifier);
@@ -422,6 +445,20 @@ bool DatabaseTracker::LazyInit() {
DCHECK(!databases_table_.get());
DCHECK(!meta_table_.get());
+ // If there are left-over directories from failed deletion attempts, clean
+ // them up.
+ if (file_util::DirectoryExists(db_dir_)) {
+ file_util::FileEnumerator directories(
+ db_dir_,
+ false,
+ file_util::FileEnumerator::DIRECTORIES,
+ kTemporaryDirectoryPattern);
+ for (FilePath directory = directories.Next(); !directory.empty();
+ directory = directories.Next()) {
+ file_util::Delete(directory, true);
+ }
+ }
+
// If the tracker database exists, but it's corrupt or doesn't
// have a meta table, delete the database directory.
const FilePath kTrackerDatabaseFullPath =
@@ -747,44 +784,67 @@ void DatabaseTracker::DeleteIncognitoDBDirectory() {
file_util::Delete(incognito_db_dir, true);
}
-// static
-void DatabaseTracker::ClearLocalState(const FilePath& profile_path) {
- // TODO(michaeln): use SpecialStoragePolicy instead of kExtensionOriginPrefix
- FilePath db_dir = profile_path.Append(FilePath(kDatabaseDirectoryName));
- FilePath db_tracker = db_dir.Append(FilePath(kTrackerDatabaseFileName));
- if (file_util::DirectoryExists(db_dir) &&
- file_util::PathExists(db_tracker)) {
- scoped_ptr<sql::Connection> db_(new sql::Connection);
- if (!db_->Open(db_tracker) ||
- !db_->DoesTableExist("Databases")) {
- db_->Close();
- file_util::Delete(db_dir, true);
- return;
- } else {
- sql::Statement delete_statement(db_->GetCachedStatement(
- SQL_FROM_HERE, "DELETE FROM Databases WHERE origin NOT LIKE ?"));
- std::string filter(kExtensionOriginIdentifierPrefix);
- filter += "%";
- delete_statement.BindString(0, filter);
- if (!delete_statement.Run()) {
- db_->Close();
- file_util::Delete(db_dir, true);
- return;
- }
+void DatabaseTracker::ClearLocalState() {
+ shutting_down_ = true;
+
+ std::vector<string16> origin_identifiers;
+ GetAllOriginIdentifiers(&origin_identifiers);
+
+ for (std::vector<string16>::iterator origin = origin_identifiers.begin();
+ origin != origin_identifiers.end(); ++origin) {
+ if (special_storage_policy_.get() &&
+ special_storage_policy_->IsStorageProtected(
+ webkit_database::DatabaseUtil::GetOriginFromIdentifier(*origin))) {
+ continue;
}
- }
- file_util::FileEnumerator file_enumerator(db_dir, false,
- file_util::FileEnumerator::DIRECTORIES);
- for (FilePath file_path = file_enumerator.Next(); !file_path.empty();
- file_path = file_enumerator.Next()) {
- if (file_path.BaseName() != FilePath(kTrackerDatabaseFileName)) {
- std::string basename = file_path.BaseName().MaybeAsASCII();
- if (!basename.empty() &&
- !StartsWithASCII(basename, kExtensionOriginIdentifierPrefix, true)) {
- file_util::Delete(file_path, true);
- }
+ webkit_database::OriginInfo origin_info;
+ std::vector<string16> databases;
+ GetOriginInfo(*origin, &origin_info);
+ origin_info.GetAllDatabaseNames(&databases);
+
+ for (std::vector<string16>::iterator database = databases.begin();
+ database != databases.end(); ++database) {
+ base::PlatformFile file_handle = base::CreatePlatformFile(
+ GetFullDBFilePath(*origin, *database),
+ base::PLATFORM_FILE_OPEN_ALWAYS |
+ base::PLATFORM_FILE_SHARE_DELETE |
+ base::PLATFORM_FILE_DELETE_ON_CLOSE |
+ base::PLATFORM_FILE_READ,
+ NULL, NULL);
+ base::ClosePlatformFile(file_handle);
}
+ DeleteOrigin(*origin, true);
+ }
+}
+
+
+void DatabaseTracker::Shutdown() {
+ DCHECK(db_tracker_thread_.get());
+ DCHECK(db_tracker_thread_->BelongsToCurrentThread());
+ if (shutting_down_) {
+ NOTREACHED();
+ return;
+ }
+ if (is_incognito_)
+ DeleteIncognitoDBDirectory();
+ else if (clear_local_state_on_exit_ && LazyInit())
+ ClearLocalState();
+}
+
+void DatabaseTracker::SetClearLocalStateOnExit(bool clear_local_state_on_exit) {
+ DCHECK(db_tracker_thread_.get());
+ if (!db_tracker_thread_->BelongsToCurrentThread()) {
+ db_tracker_thread_->PostTask(FROM_HERE,
+ NewRunnableMethod(this,
+ &DatabaseTracker::SetClearLocalStateOnExit,
+ clear_local_state_on_exit));
+ return;
+ }
+ if (shutting_down_) {
+ NOTREACHED();
+ return;
}
+ clear_local_state_on_exit_ = clear_local_state_on_exit;
}
} // namespace webkit_database
« no previous file with comments | « webkit/database/database_tracker.h ('k') | webkit/database/database_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698