summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc')
-rw-r--r--chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc74
1 files changed, 56 insertions, 18 deletions
diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
index d6995788e12..4efcbb8d0da 100644
--- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
+++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc
@@ -29,8 +29,8 @@
#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
+#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
-#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
@@ -52,8 +52,6 @@ StorageNamespace::StorageNamespace(StorageController* controller,
const String& namespace_id)
: controller_(controller), namespace_id_(namespace_id) {}
-StorageNamespace::~StorageNamespace() = default;
-
// static
void StorageNamespace::ProvideSessionStorageNamespaceTo(Page& page,
WebViewClient* client) {
@@ -100,20 +98,10 @@ scoped_refptr<CachedStorageArea> StorageNamespace::GetCachedArea(
scoped_refptr<const SecurityOrigin> origin(origin_ptr);
controller_->ClearAreasIfNeeded();
- if (IsSessionStorage()) {
- EnsureConnected();
- mojo::PendingAssociatedRemote<mojom::blink::StorageArea> area_remote;
- namespace_->OpenArea(origin,
- area_remote.InitWithNewEndpointAndPassReceiver());
- result = CachedStorageArea::CreateForSessionStorage(
- origin, std::move(area_remote), controller_->IPCTaskRunner(), this);
- } else {
- mojo::PendingRemote<mojom::blink::StorageArea> area_remote;
- controller_->storage_partition_service()->OpenLocalStorage(
- origin, area_remote.InitWithNewPipeAndPassReceiver());
- result = CachedStorageArea::CreateForLocalStorage(
- origin, std::move(area_remote), controller_->IPCTaskRunner(), this);
- }
+ result = base::MakeRefCounted<CachedStorageArea>(
+ IsSessionStorage() ? CachedStorageArea::AreaType::kSessionStorage
+ : CachedStorageArea::AreaType::kLocalStorage,
+ origin, controller_->IPCTaskRunner(), this);
cached_areas_.insert(std::move(origin), result);
return result;
}
@@ -121,7 +109,40 @@ scoped_refptr<CachedStorageArea> StorageNamespace::GetCachedArea(
void StorageNamespace::CloneTo(const String& target) {
DCHECK(IsSessionStorage()) << "Cannot clone a local storage namespace.";
EnsureConnected();
+
+ // Spec requires that all mutations on storage areas *before* cloning are
+ // visible in the clone and that no mutations on the original storage areas
+ // *after* cloning, are visible in the clone. Consider the following scenario
+ // in the comments below:
+ //
+ // 1. Area A calls Put("x", 42)
+ // 2. Area B calls Put("y", 13)
+ // 3. Area A & B's StorageNamespace gets CloneTo()'d to a new namespace
+ // 4. Area A calls Put("x", 43) in the original namespace
+ //
+ // First, we synchronize StorageNamespace against every cached StorageArea.
+ // This ensures that all StorageArea operations (e.g. Put, Delete) up to this
+ // point will have executed before the StorageNamespace implementation is able
+ // to receive or process the following |Clone()| call. Given the above
+ // example, this would mean that A.x=42 and B.y=13 definitely WILL be present
+ // in the cloned namespace.
+ for (auto& entry : cached_areas_) {
+ namespace_.PauseReceiverUntilFlushCompletes(
+ entry.value->RemoteArea().FlushAsync());
+ }
+
namespace_->Clone(target);
+
+ // Finally, we synchronize every StorageArea against StorageNamespace. This
+ // ensures that any future calls on each StorageArea cannot be received and
+ // processed until after the above |Clone()| call executes. Given the example
+ // above, this would mean that A.x=43 definitely WILL NOT be present in the
+ // cloned namespace; only the original namespace will be updated, and A.x will
+ // still hold a value of 42 in the new clone.
+ for (auto& entry : cached_areas_) {
+ entry.value->RemoteArea().PauseReceiverUntilFlushCompletes(
+ namespace_.FlushAsync());
+ }
}
size_t StorageNamespace::TotalCacheSize() const {
@@ -167,11 +188,28 @@ void StorageNamespace::DidDispatchStorageEvent(const SecurityOrigin* origin,
}
}
+void StorageNamespace::BindStorageArea(
+ const scoped_refptr<const SecurityOrigin>& origin,
+ mojo::PendingReceiver<mojom::blink::StorageArea> receiver) {
+ if (IsSessionStorage()) {
+ controller_->dom_storage()->BindSessionStorageArea(origin, namespace_id_,
+ std::move(receiver));
+ } else {
+ controller_->dom_storage()->OpenLocalStorage(origin, std::move(receiver));
+ }
+}
+
+void StorageNamespace::ResetStorageAreaAndNamespaceConnections() {
+ for (const auto& area : cached_areas_)
+ area.value->ResetConnection();
+ namespace_.reset();
+}
+
void StorageNamespace::EnsureConnected() {
DCHECK(IsSessionStorage());
if (namespace_)
return;
- controller_->storage_partition_service()->OpenSessionStorage(
+ controller_->dom_storage()->BindSessionStorageNamespace(
namespace_id_,
namespace_.BindNewPipeAndPassReceiver(controller_->IPCTaskRunner()));
}