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 f9d530a65ecf751e44d90a5e83690fc2ce10b0e6..612d70a6c59c36b16dbce9e46fb88f2c6d109d54 100644 |
--- a/webkit/dom_storage/dom_storage_context.cc |
+++ b/webkit/dom_storage/dom_storage_context.cc |
@@ -9,10 +9,13 @@ |
#include "base/file_util.h" |
#include "base/location.h" |
#include "base/time.h" |
+#include "chrome/common/guid.h" // FIXME: layering violation? |
#include "webkit/dom_storage/dom_storage_area.h" |
+#include "webkit/dom_storage/dom_storage_database.h" |
#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; |
@@ -37,6 +40,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() { |
@@ -86,6 +93,7 @@ void DomStorageContext::GetUsageInfo(std::vector<UsageInfo>* infos, |
infos->push_back(info); |
} |
} |
+ // FIXME(marja): Get usage infos for sessionStorage (crbug.com/123599). |
} |
void DomStorageContext::DeleteOrigin(const GURL& origin) { |
@@ -109,6 +117,18 @@ void DomStorageContext::Shutdown() { |
for (; it != namespaces_.end(); ++it) |
it->second->Shutdown(); |
+ // Delete data from sessionStorage. If the previous exit was unclean, the |
+ // session storage backing might contain leftover data. Delete it now. |
+ if (session_storage_database_.get()) { |
+ bool success = task_runner_->PostShutdownBlockingTask( |
+ FROM_HERE, |
+ DomStorageTaskRunner::COMMIT_SEQUENCE, |
+ base::Bind(&DomStorageContext::DeleteLeftoverDataInCommitSequence, |
+ this)); |
+ DCHECK(success); |
+ } |
+ |
+ // Delete data from localStorage. |
if (localstorage_directory_.empty()) |
return; |
@@ -170,33 +190,69 @@ void DomStorageContext::NotifyAreaCleared( |
OnDomStorageAreaCleared(area, page_url)); |
} |
+std::string DomStorageContext::AllocatePersistentSessionId() { |
+ std::string guid = guid::GenerateGUID(); |
+ std::replace(guid.begin(), guid.end(), '-', '_'); |
+ return guid; |
+} |
+ |
void DomStorageContext::CreateSessionNamespace( |
- int64 namespace_id) { |
+ int64 namespace_id, |
+ const std::string& persistent_namespace_id) { |
if (is_shutdown_) |
return; |
DCHECK(namespace_id != kLocalStorageNamespaceId); |
DCHECK(namespaces_.find(namespace_id) == namespaces_.end()); |
namespaces_[namespace_id] = new DomStorageNamespace( |
- namespace_id, task_runner_); |
+ namespace_id, persistent_namespace_id, session_storage_database_.get(), |
+ task_runner_); |
} |
void DomStorageContext::DeleteSessionNamespace( |
int64 namespace_id) { |
DCHECK_NE(kLocalStorageNamespaceId, namespace_id); |
+ 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 (doomed_persistent_session_ids_.find(persistent_namespace_id) != |
+ doomed_persistent_session_ids_.end()) { |
+ 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 leftover data deletion |
+ // (DeleteLeftoverDataInCommitSequence). |
+ protected_persistent_session_ids_.insert(persistent_namespace_id); |
+ } |
+ } |
namespaces_.erase(namespace_id); |
+ doomed_persistent_session_ids_.erase(persistent_namespace_id); |
} |
void DomStorageContext::CloneSessionNamespace( |
- int64 existing_id, int64 new_id) { |
+ int64 existing_id, int64 new_id, |
+ const std::string& new_persistent_id) { |
if (is_shutdown_) |
return; |
DCHECK_NE(kLocalStorageNamespaceId, existing_id); |
DCHECK_NE(kLocalStorageNamespaceId, new_id); |
StorageNamespaceMap::iterator found = namespaces_.find(existing_id); |
if (found != namespaces_.end()) |
- namespaces_[new_id] = found->second->Clone(new_id); |
+ namespaces_[new_id] = found->second->Clone(new_id, new_persistent_id); |
else |
- CreateSessionNamespace(new_id); |
+ CreateSessionNamespace(new_id, new_persistent_id); |
+} |
+ |
+void DomStorageContext::DoomSessionStorage( |
+ const std::string& persistent_namespace_id) { |
+ doomed_persistent_session_ids_.insert(persistent_namespace_id); |
} |
void DomStorageContext::ClearSessionOnlyOrigins() { |
@@ -220,4 +276,24 @@ void DomStorageContext::ClearSessionOnlyOrigins() { |
} |
} |
+void DomStorageContext::DeleteLeftoverDataInCommitSequence() { |
+ 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(); |
+ 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()) |
+ session_storage_database_->DeleteNamespace(*it); |
+ } |
+} |
+ |
} // namespace dom_storage |