summaryrefslogtreecommitdiffstats
path: root/webkit/database
diff options
context:
space:
mode:
authordumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-12 19:24:04 +0000
committerdumi@chromium.org <dumi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-12 19:24:04 +0000
commit2b0ec8bb8b1d5e113ad072b27c3f157d985c6b21 (patch)
tree7fd39372550d1bbb60dba7483151344a06c3ca60 /webkit/database
parentd84ac11ef8abf2366f8544fe76db3cb0e645e177 (diff)
downloadchromium_src-2b0ec8bb8b1d5e113ad072b27c3f157d985c6b21.zip
chromium_src-2b0ec8bb8b1d5e113ad072b27c3f157d985c6b21.tar.gz
chromium_src-2b0ec8bb8b1d5e113ad072b27c3f157d985c6b21.tar.bz2
Ask renderers to immediately close all DB handles to a database file
when the file needs to be deleted. TEST=none BUG=none Review URL: http://codereview.chromium.org/594002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38911 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/database')
-rw-r--r--webkit/database/database_connections.cc5
-rw-r--r--webkit/database/database_connections.h9
-rw-r--r--webkit/database/database_tracker.cc82
-rw-r--r--webkit/database/database_tracker.h14
-rw-r--r--webkit/database/database_tracker_unittest.cc3
5 files changed, 99 insertions, 14 deletions
diff --git a/webkit/database/database_connections.cc b/webkit/database/database_connections.cc
index c6e9609..05efb1e 100644
--- a/webkit/database/database_connections.cc
+++ b/webkit/database/database_connections.cc
@@ -50,7 +50,8 @@ void DatabaseConnections::RemoveAllConnections() {
}
void DatabaseConnections::RemoveConnections(
- const DatabaseConnections& connections) {
+ const DatabaseConnections& connections,
+ std::vector<std::pair<string16, string16> >* closed_dbs) {
for (OriginConnections::const_iterator origin_it =
connections.connections_.begin();
origin_it != connections.connections_.end();
@@ -59,6 +60,8 @@ void DatabaseConnections::RemoveConnections(
for (DBConnections::const_iterator db_it = db_connections.begin();
db_it != db_connections.end(); db_it++) {
RemoveConnectionsHelper(origin_it->first, db_it->first, db_it->second);
+ if (!IsDatabaseOpened(origin_it->first, db_it->first))
+ closed_dbs->push_back(std::make_pair(origin_it->first, db_it->first));
}
}
}
diff --git a/webkit/database/database_connections.h b/webkit/database/database_connections.h
index 02941c8..433bb3f 100644
--- a/webkit/database/database_connections.h
+++ b/webkit/database/database_connections.h
@@ -5,9 +5,10 @@
#ifndef WEBKIT_DATABASE_DATABASE_CONNECTIONS_H_
#define WEBKIT_DATABASE_DATABASE_CONNECTIONS_H_
-#include "base/string16.h"
-
#include <map>
+#include <vector>
+
+#include "base/string16.h"
namespace webkit_database {
@@ -25,7 +26,9 @@ class DatabaseConnections {
void RemoveConnection(const string16& origin_identifier,
const string16& database_name);
void RemoveAllConnections();
- void RemoveConnections(const DatabaseConnections& connections);
+ void RemoveConnections(
+ const DatabaseConnections& connections,
+ std::vector<std::pair<string16, string16> >* closed_dbs);
private:
typedef std::map<string16, int> DBConnections;
diff --git a/webkit/database/database_tracker.cc b/webkit/database/database_tracker.cc
index 15079ff..f2bb4ae 100644
--- a/webkit/database/database_tracker.cc
+++ b/webkit/database/database_tracker.cc
@@ -36,11 +36,14 @@ DatabaseTracker::DatabaseTracker(const FilePath& profile_path)
db_(new sql::Connection()),
databases_table_(NULL),
meta_table_(NULL),
+ dbs_deleted_callback_(NULL),
default_quota_(5 * 1024 * 1024) {
}
DatabaseTracker::~DatabaseTracker() {
DCHECK(observers_.size() == 0);
+ DCHECK(dbs_to_be_deleted_.empty());
+ DCHECK(!dbs_deleted_callback_);
}
void DatabaseTracker::SetDefaultQuota(int64 quota) {
@@ -84,10 +87,34 @@ void DatabaseTracker::DatabaseModified(const string16& origin_identifier,
void DatabaseTracker::DatabaseClosed(const string16& origin_identifier,
const string16& database_name) {
database_connections_.RemoveConnection(origin_identifier, database_name);
+ if (!database_connections_.IsDatabaseOpened(origin_identifier, database_name))
+ DeleteDatabaseIfNeeded(origin_identifier, database_name);
}
void DatabaseTracker::CloseDatabases(const DatabaseConnections& connections) {
- database_connections_.RemoveConnections(connections);
+ std::vector<std::pair<string16, string16> > closed_dbs;
+ database_connections_.RemoveConnections(connections, &closed_dbs);
+ for (std::vector<std::pair<string16, string16> >::iterator it =
+ closed_dbs.begin(); it != closed_dbs.end(); ++it) {
+ DeleteDatabaseIfNeeded(it->first, it->second);
+ }
+}
+
+void DatabaseTracker::DeleteDatabaseIfNeeded(const string16& origin_identifier,
+ const string16& database_name) {
+ DCHECK(!database_connections_.IsDatabaseOpened(origin_identifier,
+ database_name));
+ if (IsDatabaseScheduledForDeletion(origin_identifier, database_name)) {
+ DeleteDatabase(origin_identifier, database_name);
+ dbs_to_be_deleted_[origin_identifier].erase(database_name);
+ if (dbs_to_be_deleted_[origin_identifier].empty())
+ dbs_to_be_deleted_.erase(origin_identifier);
+ if (dbs_to_be_deleted_.empty()) {
+ DCHECK(dbs_deleted_callback_);
+ dbs_deleted_callback_->Run(net::OK);
+ dbs_deleted_callback_ = NULL;
+ }
+ }
}
void DatabaseTracker::AddObserver(Observer* observer) {
@@ -195,6 +222,18 @@ bool DatabaseTracker::DeleteOrigin(const string16& origin_identifier) {
return true;
}
+bool DatabaseTracker::IsDatabaseScheduledForDeletion(
+ const string16& origin_identifier,
+ const string16& database_name) {
+ std::map<string16, std::set<string16> >::iterator it =
+ dbs_to_be_deleted_.find(origin_identifier);
+ if (it == dbs_to_be_deleted_.end())
+ return false;
+
+ std::set<string16>& databases = it->second;
+ return (databases.find(database_name) != databases.end());
+}
+
bool DatabaseTracker::LazyInit() {
if (!initialized_) {
DCHECK(!db_->is_open());
@@ -339,15 +378,31 @@ int64 DatabaseTracker::UpdateCachedDatabaseFileSize(
return new_size;
}
+void DatabaseTracker::ScheduleDatabaseForDeletion(
+ const string16& origin_identifier,
+ const string16& database_name) {
+ DCHECK(database_connections_.IsDatabaseOpened(origin_identifier,
+ database_name));
+ dbs_to_be_deleted_[origin_identifier].insert(database_name);
+ FOR_EACH_OBSERVER(Observer, observers_, OnDatabaseScheduledForDeletion(
+ origin_identifier, database_name));
+}
+
int DatabaseTracker::DeleteDataModifiedSince(
const base::Time& cutoff,
net::CompletionCallback* callback) {
- if (!LazyInit())
+ // Check for reentrancy.
+ if (dbs_deleted_callback_ || !LazyInit())
return net::ERR_FAILED;
+ DCHECK(callback);
+ dbs_deleted_callback_ = callback;
+
std::vector<string16> origins;
- if (!databases_table_->GetAllOrigins(&origins))
+ if (!databases_table_->GetAllOrigins(&origins)) {
+ dbs_deleted_callback_ = NULL;
return net::ERR_FAILED;
+ }
int rv = net::OK;
for (std::vector<string16>::const_iterator ori = origins.begin();
ori != origins.end(); ++ori) {
@@ -360,19 +415,26 @@ int DatabaseTracker::DeleteDataModifiedSince(
}
for (std::vector<DatabaseDetails>::const_iterator db = details.begin();
db != details.end(); ++db) {
- // Check if the database is opened by any renderer.
- if (database_connections_.IsDatabaseOpened(*ori, db->database_name)) {
- // TODO(jochen): make renderer close the database.
- rv = net::ERR_FAILED;
- continue;
- }
FilePath db_file = GetFullDBFilePath(*ori, db->database_name);
file_util::FileInfo file_info;
file_util::GetFileInfo(db_file, &file_info);
- if (file_info.last_modified >= cutoff)
+ if (file_info.last_modified < cutoff)
+ continue;
+
+ // Check if the database is opened by any renderer.
+ if (database_connections_.IsDatabaseOpened(*ori, db->database_name)) {
+ ScheduleDatabaseForDeletion(*ori, db->database_name);
+ rv = net::ERR_IO_PENDING;
+ } else {
DeleteDatabase(*ori, db->database_name);
+ }
}
}
+
+ if (rv != net::ERR_IO_PENDING) {
+ dbs_to_be_deleted_.clear();
+ dbs_deleted_callback_ = NULL;
+ }
return rv;
}
diff --git a/webkit/database/database_tracker.h b/webkit/database/database_tracker.h
index 93a60e5..a6c7720 100644
--- a/webkit/database/database_tracker.h
+++ b/webkit/database/database_tracker.h
@@ -6,6 +6,7 @@
#define WEBKIT_DATABASE_DATABASE_TRACKER_H_
#include <map>
+#include <set>
#include "base/file_path.h"
#include "base/observer_list.h"
@@ -92,6 +93,9 @@ class DatabaseTracker
const string16& database_name,
int64 database_size,
int64 space_available) = 0;
+ virtual void OnDatabaseScheduledForDeletion(
+ const string16& origin_identifier,
+ const string16& database_name) = 0;
virtual ~Observer() {}
};
@@ -111,6 +115,8 @@ class DatabaseTracker
void DatabaseClosed(const string16& origin_identifier,
const string16& database_name);
void CloseDatabases(const DatabaseConnections& connections);
+ void DeleteDatabaseIfNeeded(const string16& origin_identifier,
+ const string16& database_name);
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
@@ -126,6 +132,8 @@ class DatabaseTracker
bool DeleteDatabase(const string16& origin_identifier,
const string16& database_name);
bool DeleteOrigin(const string16& origin_identifier);
+ bool IsDatabaseScheduledForDeletion(const string16& origin_identifier,
+ const string16& database_name);
// Delete any databases that have been touched since the cutoff date that's
// supplied. Returns net::OK on success, net::FAILED if not all databases
@@ -178,6 +186,8 @@ class DatabaseTracker
int64 UpdateCachedDatabaseFileSize(const string16& origin_identifier,
const string16& database_name);
+ void ScheduleDatabaseForDeletion(const string16& origin_identifier,
+ const string16& database_name);
bool initialized_;
const FilePath db_dir_;
@@ -189,6 +199,10 @@ class DatabaseTracker
std::map<string16, CachedOriginInfo> origins_info_map_;
DatabaseConnections database_connections_;
+ // The set of databases that should be deleted but are still opened
+ std::map<string16, std::set<string16> > dbs_to_be_deleted_;
+ net::CompletionCallback* dbs_deleted_callback_;
+
// Default quota for all origins; changed only by tests
int64 default_quota_;
diff --git a/webkit/database/database_tracker_unittest.cc b/webkit/database/database_tracker_unittest.cc
index 8b44a451..0ed707d 100644
--- a/webkit/database/database_tracker_unittest.cc
+++ b/webkit/database/database_tracker_unittest.cc
@@ -26,6 +26,9 @@ class TestObserver : public webkit_database::DatabaseTracker::Observer {
database_size_ = database_size;
space_available_ = space_available;
}
+ virtual void OnDatabaseScheduledForDeletion(const string16& origin_identifier,
+ const string16& database_name) {
+ }
bool DidReceiveNewNotification() {
bool temp_new_notification_received = new_notification_received_;
new_notification_received_ = false;