diff options
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.cc | 74 |
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())); } |