diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-06-18 14:10:49 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2015-06-18 13:53:24 +0000 |
commit | 813fbf95af77a531c57a8c497345ad2c61d475b3 (patch) | |
tree | 821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/content/browser/dom_storage/dom_storage_namespace.cc | |
parent | af6588f8d723931a298c995fa97259bb7f7deb55 (diff) |
BASELINE: Update chromium to 44.0.2403.47
Change-Id: Ie056fedba95cf5e5c76b30c4b2c80fca4764aa2f
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/content/browser/dom_storage/dom_storage_namespace.cc')
-rw-r--r-- | chromium/content/browser/dom_storage/dom_storage_namespace.cc | 286 |
1 files changed, 22 insertions, 264 deletions
diff --git a/chromium/content/browser/dom_storage/dom_storage_namespace.cc b/chromium/content/browser/dom_storage/dom_storage_namespace.cc index fb76b6764ed..f554ac58814 100644 --- a/chromium/content/browser/dom_storage/dom_storage_namespace.cc +++ b/chromium/content/browser/dom_storage/dom_storage_namespace.cc @@ -4,40 +4,23 @@ #include "content/browser/dom_storage/dom_storage_namespace.h" -#include <set> -#include <utility> - #include "base/basictypes.h" #include "base/bind.h" #include "base/location.h" #include "base/logging.h" -#include "base/stl_util.h" #include "content/browser/dom_storage/dom_storage_area.h" -#include "content/browser/dom_storage/dom_storage_context_impl.h" #include "content/browser/dom_storage/dom_storage_task_runner.h" #include "content/browser/dom_storage/session_storage_database.h" #include "content/common/dom_storage/dom_storage_types.h" -#include "content/public/common/child_process_host.h" namespace content { -namespace { - -static const unsigned int kMaxTransactionLogEntries = 8 * 1024; - -} // namespace - DOMStorageNamespace::DOMStorageNamespace( const base::FilePath& directory, DOMStorageTaskRunner* task_runner) : namespace_id_(kLocalStorageNamespaceId), directory_(directory), - task_runner_(task_runner), - num_aliases_(0), - old_master_for_close_area_(NULL), - master_alias_count_decremented_(false), - ready_for_deletion_pending_aliases_(false), - must_persist_at_shutdown_(false) { + task_runner_(task_runner) { } DOMStorageNamespace::DOMStorageNamespace( @@ -48,23 +31,14 @@ DOMStorageNamespace::DOMStorageNamespace( : namespace_id_(namespace_id), persistent_namespace_id_(persistent_namespace_id), task_runner_(task_runner), - session_storage_database_(session_storage_database), - num_aliases_(0), - old_master_for_close_area_(NULL), - master_alias_count_decremented_(false), - ready_for_deletion_pending_aliases_(false), - must_persist_at_shutdown_(false) { + session_storage_database_(session_storage_database) { DCHECK_NE(kLocalStorageNamespaceId, namespace_id); } DOMStorageNamespace::~DOMStorageNamespace() { - STLDeleteValues(&transactions_); - DecrementMasterAliasCount(); } DOMStorageArea* DOMStorageNamespace::OpenStorageArea(const GURL& origin) { - if (alias_master_namespace_.get()) - return alias_master_namespace_->OpenStorageArea(origin); if (AreaHolder* holder = GetAreaHolder(origin)) { ++(holder->open_count_); return holder->area_.get(); @@ -83,14 +57,6 @@ DOMStorageArea* DOMStorageNamespace::OpenStorageArea(const GURL& origin) { void DOMStorageNamespace::CloseStorageArea(DOMStorageArea* area) { AreaHolder* holder = GetAreaHolder(area->origin()); - if (alias_master_namespace_.get()) { - DCHECK(!holder); - if (old_master_for_close_area_) - old_master_for_close_area_->CloseStorageArea(area); - else - alias_master_namespace_->CloseStorageArea(area); - return; - } DCHECK(holder); DCHECK_EQ(holder->area_.get(), area); --(holder->open_count_); @@ -99,8 +65,6 @@ void DOMStorageNamespace::CloseStorageArea(DOMStorageArea* area) { } DOMStorageArea* DOMStorageNamespace::GetOpenStorageArea(const GURL& origin) { - if (alias_master_namespace_.get()) - return alias_master_namespace_->GetOpenStorageArea(origin); AreaHolder* holder = GetAreaHolder(origin); if (holder && holder->open_count_) return holder->area_.get(); @@ -110,10 +74,6 @@ DOMStorageArea* DOMStorageNamespace::GetOpenStorageArea(const GURL& origin) { DOMStorageNamespace* DOMStorageNamespace::Clone( int64 clone_namespace_id, const std::string& clone_persistent_namespace_id) { - if (alias_master_namespace_.get()) { - return alias_master_namespace_->Clone(clone_namespace_id, - clone_persistent_namespace_id); - } DCHECK_NE(kLocalStorageNamespaceId, namespace_id_); DCHECK_NE(kLocalStorageNamespaceId, clone_namespace_id); DOMStorageNamespace* clone = new DOMStorageNamespace( @@ -138,34 +98,8 @@ DOMStorageNamespace* DOMStorageNamespace::Clone( return clone; } -DOMStorageNamespace* DOMStorageNamespace::CreateAlias( - int64 alias_namespace_id) { - // Creates an alias of the current DOMStorageNamespace. - // The alias will have a reference to this namespace (called the master), - // and all operations will be redirected to the master (in particular, - // the alias will never open any areas of its own, but always redirect - // to the master). Accordingly, an alias will also never undergo the shutdown - // procedure which initiates persisting to disk, since there is never any data - // of its own to persist to disk. DOMStorageContextImpl is the place where - // shutdowns are initiated, but only for non-alias DOMStorageNamespaces. - DCHECK_NE(kLocalStorageNamespaceId, namespace_id_); - DCHECK_NE(kLocalStorageNamespaceId, alias_namespace_id); - DOMStorageNamespace* alias = new DOMStorageNamespace( - alias_namespace_id, persistent_namespace_id_, - session_storage_database_.get(), task_runner_.get()); - if (alias_master_namespace_.get() != NULL) { - DCHECK(alias_master_namespace_->alias_master_namespace_.get() == NULL); - alias->alias_master_namespace_ = alias_master_namespace_; - } else { - alias->alias_master_namespace_ = this; - } - alias->alias_master_namespace_->num_aliases_++; - return alias; -} - void DOMStorageNamespace::DeleteLocalStorageOrigin(const GURL& origin) { DCHECK(!session_storage_database_.get()); - DCHECK(!alias_master_namespace_.get()); AreaHolder* holder = GetAreaHolder(origin); if (holder) { holder->area_->DeleteOrigin(); @@ -179,34 +113,33 @@ void DOMStorageNamespace::DeleteLocalStorageOrigin(const GURL& origin) { } void DOMStorageNamespace::DeleteSessionStorageOrigin(const GURL& origin) { - if (alias_master_namespace_.get()) { - alias_master_namespace_->DeleteSessionStorageOrigin(origin); - return; - } DOMStorageArea* area = OpenStorageArea(origin); area->FastClear(); CloseStorageArea(area); } void DOMStorageNamespace::PurgeMemory(PurgeOption option) { - if (alias_master_namespace_.get()) { - alias_master_namespace_->PurgeMemory(option); - return; - } if (directory_.empty()) return; // We can't purge w/o backing on disk. AreaMap::iterator it = areas_.begin(); while (it != areas_.end()) { - // Leave it alone if changes are pending - if (it->second.area_->HasUncommittedChanges()) { + const AreaHolder& holder = it->second; + + // We can't purge if there are changes pending. + if (holder.area_->HasUncommittedChanges()) { + if (holder.open_count_ == 0) { + // Schedule an immediate commit so the next time we're asked to purge, + // we can drop it from memory. + holder.area_->ScheduleImmediateCommit(); + } ++it; continue; } // If not in use, we can shut it down and remove // it from our collection entirely. - if (it->second.open_count_ == 0) { - it->second.area_->Shutdown(); + if (holder.open_count_ == 0) { + holder.area_->Shutdown(); areas_.erase(it++); continue; } @@ -214,7 +147,7 @@ void DOMStorageNamespace::PurgeMemory(PurgeOption option) { if (option == PURGE_AGGRESSIVE) { // If aggressive is true, we clear caches and such // for opened areas. - it->second.area_->PurgeMemory(); + holder.area_->PurgeMemory(); } ++it; @@ -227,9 +160,15 @@ void DOMStorageNamespace::Shutdown() { it->second.area_->Shutdown(); } +void DOMStorageNamespace::Flush() { + for (auto& entry : areas_) { + if (!entry.second.area_->HasUncommittedChanges()) + continue; + entry.second.area_->ScheduleImmediateCommit(); + } +} + unsigned int DOMStorageNamespace::CountInMemoryAreas() const { - if (alias_master_namespace_.get()) - return alias_master_namespace_->CountInMemoryAreas(); unsigned int area_count = 0; for (AreaMap::const_iterator it = areas_.begin(); it != areas_.end(); ++it) { if (it->second.area_->IsLoadedInMemory()) @@ -246,187 +185,6 @@ DOMStorageNamespace::GetAreaHolder(const GURL& origin) { return &(found->second); } -void DOMStorageNamespace::AddTransactionLogProcessId(int process_id) { - DCHECK(process_id != ChildProcessHost::kInvalidUniqueID); - DCHECK(transactions_.count(process_id) == 0); - TransactionData* transaction_data = new TransactionData; - transactions_[process_id] = transaction_data; -} - -void DOMStorageNamespace::RemoveTransactionLogProcessId(int process_id) { - DCHECK(process_id != ChildProcessHost::kInvalidUniqueID); - DCHECK(transactions_.count(process_id) == 1); - delete transactions_[process_id]; - transactions_.erase(process_id); -} - -SessionStorageNamespace::MergeResult DOMStorageNamespace::Merge( - bool actually_merge, - int process_id, - DOMStorageNamespace* other, - DOMStorageContextImpl* context) { - if (!alias_master_namespace()) - return SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_ALIAS; - if (transactions_.count(process_id) < 1) - return SessionStorageNamespace::MERGE_RESULT_NOT_LOGGING; - TransactionData* data = transactions_[process_id]; - if (data->max_log_size_exceeded) - return SessionStorageNamespace::MERGE_RESULT_TOO_MANY_TRANSACTIONS; - if (data->log.size() < 1) { - if (actually_merge) - SwitchToNewAliasMaster(other, context); - return SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS; - } - - // skip_areas and skip_keys store areas and (area, key) pairs, respectively, - // that have already been handled previously. Any further modifications to - // them will not change the result of the hypothetical merge. - std::set<GURL> skip_areas; - typedef std::pair<GURL, base::string16> OriginKey; - std::set<OriginKey> skip_keys; - // Indicates whether we could still merge the namespaces preserving all - // individual transactions. - for (unsigned int i = 0; i < data->log.size(); i++) { - TransactionRecord& transaction = data->log[i]; - if (transaction.transaction_type == TRANSACTION_CLEAR) { - skip_areas.insert(transaction.origin); - continue; - } - if (skip_areas.find(transaction.origin) != skip_areas.end()) - continue; - if (skip_keys.find(OriginKey(transaction.origin, transaction.key)) - != skip_keys.end()) { - continue; - } - if (transaction.transaction_type == TRANSACTION_REMOVE || - transaction.transaction_type == TRANSACTION_WRITE) { - skip_keys.insert(OriginKey(transaction.origin, transaction.key)); - continue; - } - if (transaction.transaction_type == TRANSACTION_READ) { - DOMStorageArea* area = other->OpenStorageArea(transaction.origin); - base::NullableString16 other_value = area->GetItem(transaction.key); - other->CloseStorageArea(area); - if (transaction.value != other_value) - return SessionStorageNamespace::MERGE_RESULT_NOT_MERGEABLE; - continue; - } - NOTREACHED(); - } - if (!actually_merge) - return SessionStorageNamespace::MERGE_RESULT_MERGEABLE; - - // Actually perform the merge. - - for (unsigned int i = 0; i < data->log.size(); i++) { - TransactionRecord& transaction = data->log[i]; - if (transaction.transaction_type == TRANSACTION_READ) - continue; - DOMStorageArea* area = other->OpenStorageArea(transaction.origin); - if (transaction.transaction_type == TRANSACTION_CLEAR) { - area->Clear(); - if (context) - context->NotifyAreaCleared(area, transaction.page_url); - } - if (transaction.transaction_type == TRANSACTION_REMOVE) { - base::string16 old_value; - area->RemoveItem(transaction.key, &old_value); - if (context) { - context->NotifyItemRemoved(area, transaction.key, old_value, - transaction.page_url); - } - } - if (transaction.transaction_type == TRANSACTION_WRITE) { - base::NullableString16 old_value; - area->SetItem(transaction.key, base::string16(transaction.value.string()), - &old_value); - if (context) { - context->NotifyItemSet(area, transaction.key,transaction.value.string(), - old_value, transaction.page_url); - } - } - other->CloseStorageArea(area); - } - - SwitchToNewAliasMaster(other, context); - return SessionStorageNamespace::MERGE_RESULT_MERGEABLE; -} - -bool DOMStorageNamespace::IsLoggingRenderer(int process_id) { - DCHECK(process_id != ChildProcessHost::kInvalidUniqueID); - if (transactions_.count(process_id) < 1) - return false; - return !transactions_[process_id]->max_log_size_exceeded; -} - -void DOMStorageNamespace::AddTransaction( - int process_id, const TransactionRecord& transaction) { - if (!IsLoggingRenderer(process_id)) - return; - TransactionData* transaction_data = transactions_[process_id]; - DCHECK(transaction_data); - if (transaction_data->max_log_size_exceeded) - return; - transaction_data->log.push_back(transaction); - if (transaction_data->log.size() > kMaxTransactionLogEntries) { - transaction_data->max_log_size_exceeded = true; - transaction_data->log.clear(); - } -} - -bool DOMStorageNamespace::DecrementMasterAliasCount() { - if (!alias_master_namespace_.get() || master_alias_count_decremented_) - return false; - DCHECK_GT(alias_master_namespace_->num_aliases_, 0); - alias_master_namespace_->num_aliases_--; - master_alias_count_decremented_ = true; - return (alias_master_namespace_->num_aliases_ == 0); -} - -void DOMStorageNamespace::SwitchToNewAliasMaster( - DOMStorageNamespace* new_master, - DOMStorageContextImpl* context) { - DCHECK(alias_master_namespace()); - scoped_refptr<DOMStorageNamespace> old_master = alias_master_namespace(); - if (new_master->alias_master_namespace()) - new_master = new_master->alias_master_namespace(); - DCHECK(!new_master->alias_master_namespace()); - DCHECK(old_master.get() != this); - DCHECK(old_master.get() != new_master); - DecrementMasterAliasCount(); - alias_master_namespace_ = new_master; - alias_master_namespace_->num_aliases_++; - master_alias_count_decremented_ = false; - // There are three things that we need to clean up: - // -- the old master may ready for shutdown, if its last alias has disappeared - // -- The dom_storage hosts need to close and reopen their areas, so that - // they point to the correct new areas. - // -- The renderers will need to reset their local caches. - // All three of these things are accomplished with the following call below. - // |context| will be NULL in unit tests, which is when this will - // not apply, of course. - // During this call, open areas will be closed & reopened, so that they now - // come from the correct new master. Therefore, we must send close operations - // to the old master. - old_master_for_close_area_ = old_master.get(); - if (context) - context->NotifyAliasSessionMerged(namespace_id(), old_master.get()); - old_master_for_close_area_ = NULL; -} - -DOMStorageNamespace::TransactionData::TransactionData() - : max_log_size_exceeded(false) { -} - -DOMStorageNamespace::TransactionData::~TransactionData() { -} - -DOMStorageNamespace::TransactionRecord::TransactionRecord() { -} - -DOMStorageNamespace::TransactionRecord::~TransactionRecord() { -} - // AreaHolder DOMStorageNamespace::AreaHolder::AreaHolder() |