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

Unified Diff: webkit/dom_storage/dom_storage_context.cc

Issue 9963107: Persist sessionStorage on disk. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: session only rules Created 8 years, 6 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
Index: webkit/dom_storage/dom_storage_context.cc
diff --git a/webkit/dom_storage/dom_storage_context.cc b/webkit/dom_storage/dom_storage_context.cc
index 9d431bae1b3cae8b5e372f5d0372078e4f9dc3db..fd9e056445b2124fa657e625bc7fedc0d7f88eff 100644
--- a/webkit/dom_storage/dom_storage_context.cc
+++ b/webkit/dom_storage/dom_storage_context.cc
@@ -15,12 +15,15 @@
#include "webkit/dom_storage/dom_storage_namespace.h"
#include "webkit/dom_storage/dom_storage_task_runner.h"
#include "webkit/dom_storage/dom_storage_types.h"
+#include "webkit/dom_storage/session_storage_database.h"
#include "webkit/quota/special_storage_policy.h"
using file_util::FileEnumerator;
namespace dom_storage {
+static const int kSessionStoraceScavengingSeconds = 60;
+
DomStorageContext::UsageInfo::UsageInfo() : data_size(0) {}
DomStorageContext::UsageInfo::~UsageInfo() {}
@@ -39,6 +42,10 @@ DomStorageContext::DomStorageContext(
// namespace ids at one since zero is reserved for the
// kLocalStorageNamespaceId.
session_id_sequence_.GetNext();
+ if (!sessionstorage_directory_.empty()) {
+ session_storage_database_ = new SessionStorageDatabase(
+ sessionstorage_directory_);
+ }
}
DomStorageContext::~DomStorageContext() {
@@ -88,6 +95,7 @@ void DomStorageContext::GetUsageInfo(std::vector<UsageInfo>* infos,
infos->push_back(info);
}
}
+ // TODO(marja): Get usage infos for sessionStorage (crbug.com/123599).
}
void DomStorageContext::DeleteOrigin(const GURL& origin) {
@@ -111,7 +119,7 @@ void DomStorageContext::Shutdown() {
for (; it != namespaces_.end(); ++it)
it->second->Shutdown();
- if (localstorage_directory_.empty())
+ if (localstorage_directory_.empty() && !session_storage_database_.get())
return;
// Respect the content policy settings about what to
@@ -186,13 +194,32 @@ void DomStorageContext::CreateSessionNamespace(
DCHECK(namespace_id != kLocalStorageNamespaceId);
DCHECK(namespaces_.find(namespace_id) == namespaces_.end());
namespaces_[namespace_id] = new DomStorageNamespace(
- namespace_id, persistent_namespace_id, task_runner_);
+ namespace_id, persistent_namespace_id, session_storage_database_.get(),
+ task_runner_);
}
void DomStorageContext::DeleteSessionNamespace(
int64 namespace_id, bool should_persist_data) {
DCHECK_NE(kLocalStorageNamespaceId, namespace_id);
- // TODO(marja): Protect the sessionStorage data (once it's written on disk).
+ StorageNamespaceMap::const_iterator it = namespaces_.find(namespace_id);
+ if (it == namespaces_.end())
+ return;
+ std::string persistent_namespace_id = it->second->persistent_namespace_id();
+ if (session_storage_database_.get()) {
+ if (!should_persist_data) {
+ bool success = task_runner_->PostShutdownBlockingTask(
+ FROM_HERE,
+ DomStorageTaskRunner::COMMIT_SEQUENCE,
+ base::Bind(
+ base::IgnoreResult(&SessionStorageDatabase::DeleteNamespace),
+ session_storage_database_,
+ persistent_namespace_id));
+ DCHECK(success);
+ } else {
+ // Protect the persistent namespace ID from scavenging.
+ protected_persistent_session_ids_.insert(persistent_namespace_id);
+ }
+ }
namespaces_.erase(namespace_id);
}
@@ -211,23 +238,99 @@ void DomStorageContext::CloneSessionNamespace(
}
void DomStorageContext::ClearSessionOnlyOrigins() {
- std::vector<UsageInfo> infos;
- const bool kDontIncludeFileInfo = false;
- GetUsageInfo(&infos, kDontIncludeFileInfo);
- for (size_t i = 0; i < infos.size(); ++i) {
- const GURL& origin = infos[i].origin;
- if (special_storage_policy_->IsStorageProtected(origin))
- continue;
- if (!special_storage_policy_->IsStorageSessionOnly(origin))
- continue;
-
- const bool kNotRecursive = false;
- FilePath database_file_path = localstorage_directory_.Append(
- DomStorageArea::DatabaseFileNameFromOrigin(origin));
- file_util::Delete(database_file_path, kNotRecursive);
- file_util::Delete(
- DomStorageDatabase::GetJournalFilePath(database_file_path),
- kNotRecursive);
+ if (!localstorage_directory_.empty()) {
+ std::vector<UsageInfo> infos;
+ const bool kDontIncludeFileInfo = false;
+ GetUsageInfo(&infos, kDontIncludeFileInfo);
+ for (size_t i = 0; i < infos.size(); ++i) {
+ const GURL& origin = infos[i].origin;
+ if (special_storage_policy_->IsStorageProtected(origin))
+ continue;
+ if (!special_storage_policy_->IsStorageSessionOnly(origin))
+ continue;
+
+ const bool kNotRecursive = false;
+ FilePath database_file_path = localstorage_directory_.Append(
+ DomStorageArea::DatabaseFileNameFromOrigin(origin));
+ file_util::Delete(database_file_path, kNotRecursive);
+ file_util::Delete(
+ DomStorageDatabase::GetJournalFilePath(database_file_path),
+ kNotRecursive);
+ }
+ }
+ if (session_storage_database_.get()) {
michaeln 2012/06/26 06:15:12 this is so weird to be clearing 'session only' stu
marja 2012/06/26 14:18:05 Ack :)
+ std::vector<std::string> namespace_ids;
+ session_storage_database_->ReadNamespaceIds(&namespace_ids);
+ for (std::vector<std::string>::const_iterator it = namespace_ids.begin();
+ it != namespace_ids.end(); ++it) {
+ std::vector<GURL> origins;
+ session_storage_database_->ReadOriginsInNamespace(*it, &origins);
+
+ for (std::vector<GURL>::const_iterator origin_it = origins.begin();
+ origin_it != origins.end(); ++origin_it) {
+ if (special_storage_policy_->IsStorageProtected(*origin_it))
+ continue;
+ if (!special_storage_policy_->IsStorageSessionOnly(*origin_it))
+ continue;
+ session_storage_database_->DeleteArea(*it, *origin_it);
+ }
+ }
+ }
+}
+
+void DomStorageContext::StartScavengingUnusedSessionStorage() {
+ if (session_storage_database_.get()) {
+ bool success = task_runner_->PostShutdownBlockingTask(
+ FROM_HERE,
+ DomStorageTaskRunner::COMMIT_SEQUENCE,
+ base::Bind(
+ &DomStorageContext::FindUnusedSessionStorageInCommitSequence,
+ this));
+ DCHECK(success);
+ }
+}
+
+void DomStorageContext::FindUnusedSessionStorageInCommitSequence() {
+ DCHECK(session_storage_database_.get());
+ // Delete all namespaces which don't have an associated DomStorageNamespace
+ // alive.
+ std::set<std::string> namespace_ids_in_use;
+ for (StorageNamespaceMap::const_iterator it = namespaces_.begin();
michaeln 2012/06/26 06:15:12 The namespaces_ collection shouldn't be accessed o
marja 2012/06/26 14:18:05 How about this version which passes const std::set
+ it != namespaces_.end(); ++it)
+ namespace_ids_in_use.insert(it->second->persistent_namespace_id());
+
+ std::vector<std::string> namespace_ids;
+ session_storage_database_->ReadNamespaceIds(&namespace_ids);
+ for (std::vector<std::string>::const_iterator it = namespace_ids.begin();
+ it != namespace_ids.end(); ++it) {
+ if (namespace_ids_in_use.find(*it) == namespace_ids_in_use.end() &&
+ protected_persistent_session_ids_.find(*it) ==
+ protected_persistent_session_ids_.end()) {
+ // This namespace should get deleted.
+ deletable_persistent_namespace_ids_.push_back(*it);
+ }
+ }
+ if (!deletable_persistent_namespace_ids_.empty()) {
+ task_runner_->PostDelayedTask(
michaeln 2012/06/26 06:15:12 This will post a task to the PRIMARYsequence which
marja 2012/06/26 14:18:05 Done, yes, this was a bug, I meant COMMIT_SEQUENCE
+ FROM_HERE,
+ base::Bind(
+ &DomStorageContext::DeleteNextUnunsedNamespaceInCommitSequence,
+ this),
+ base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds));
+ }
+}
+
+void DomStorageContext::DeleteNextUnunsedNamespaceInCommitSequence() {
+ const std::string& persistent_id = deletable_persistent_namespace_ids_.back();
+ session_storage_database_->DeleteNamespace(persistent_id);
+ deletable_persistent_namespace_ids_.pop_back();
+ if (!deletable_persistent_namespace_ids_.empty()) {
+ task_runner_->PostDelayedTask(
michaeln 2012/06/26 06:15:12 Ditto about this will post something for execution
marja 2012/06/26 14:18:05 Done.
+ FROM_HERE,
+ base::Bind(
+ &DomStorageContext::DeleteNextUnunsedNamespaceInCommitSequence,
+ this),
+ base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds));
}
}

Powered by Google App Engine
This is Rietveld 408576698