Changeset 288298 in webkit


Ignore:
Timestamp:
Jan 20, 2022 9:24:01 AM (2 years ago)
Author:
sihui_liu@apple.com
Message:

Make LocalStorage prewarming async
https://bugs.webkit.org/show_bug.cgi?id=235236

Reviewed by Chris Dumez.

Source/WebCore:

  • page/DOMWindow.cpp:

(WebCore::DOMWindow::prewarmLocalStorageIfNecessary):

  • page/Frame.cpp:

(WebCore::Frame::didPrewarmLocalStorage): Deleted.
(WebCore::Frame::mayPrewarmLocalStorage const): Deleted.

  • page/Frame.h:
  • storage/StorageArea.h:

(WebCore::StorageArea::prewarm):

  • storage/StorageType.h:

Source/WebKit:

StorageAreaMap in web process needs to sync with a remote StorageArea in network process before it performs any
Web Storage operation. To connect to remote StorageArea, StorageAreaMap currently sends out two sync messages:

  1. ConnectTo*StorageArea: for getting the remote StorageAreaIdentifier
  2. getValues: for getting the content of StorageArea

We can merge these two messages into one message: ConnectToStorageAreaSync, and return both remote
StorageAreaIdentifier and content in its reply. This way, web process will not be blocked twice.

To reduce the wait time for connecting to a local StorageArea, we would prewarm LocalStorage by creating its
StorageAreaMap ahead and making it connected (r247555), but we don't actually need StorageAreaMap to be ready
for operation at this time. Therefore, a new async message ConnectToStorageArea is added to be used for
prewarming.

If LocalStorage is used immediately after prewarming, a StorageAreaMap may send ConnectToStorageAreaSync before
receiving the reply of ConnectToStorageArea. In this case, StorageAreaMap would handle ConnectToStorageAreaSync
reply before ConnectToStorageArea reply (due to the priority of sync message), and also before other async
messages (DispatchStorageEvent / ClearCache) that are sent from network process earlier before the sync reply.
To solve this, we use a message identifier to indicate the order of messages sent from network process, so
StorageAreaMap can ignore previous messages when it is already synced with a more recent version of StorageArea.

  • NetworkProcess/WebStorage/StorageArea.cpp:

(WebKit::StorageArea::clear):
(WebKit::StorageArea::dispatchEvents const):

  • NetworkProcess/storage/LocalStorageManager.cpp:

(WebKit::LocalStorageManager::connectToLocalStorageArea):
(WebKit::LocalStorageManager::connectToTransientLocalStorageArea):

  • NetworkProcess/storage/LocalStorageManager.h:
  • NetworkProcess/storage/NetworkStorageManager.cpp:

(WebKit::NetworkStorageManager::connectToStorageArea):
(WebKit::NetworkStorageManager::connectToStorageAreaSync):
(WebKit::NetworkStorageManager::connectToLocalStorageArea): Deleted.
(WebKit::NetworkStorageManager::connectToTransientLocalStorageArea): Deleted.
(WebKit::NetworkStorageManager::connectToSessionStorageArea): Deleted.
(WebKit::NetworkStorageManager::getValues): Deleted.

  • NetworkProcess/storage/NetworkStorageManager.h:
  • NetworkProcess/storage/NetworkStorageManager.messages.in:
  • NetworkProcess/storage/SessionStorageManager.cpp:

(WebKit::SessionStorageManager::connectToSessionStorageArea):

  • NetworkProcess/storage/SessionStorageManager.h:
  • NetworkProcess/storage/StorageAreaBase.cpp:

(WebKit::StorageAreaBase::nextMessageIdentifier):
(WebKit::StorageAreaBase::StorageAreaBase):
(WebKit::StorageAreaBase::addListener):
(WebKit::StorageAreaBase::notifyListenersAboutClear):
(WebKit::StorageAreaBase::dispatchEvents const):

  • NetworkProcess/storage/StorageAreaBase.h:
  • Scripts/webkit/messages.py:

(types_that_cannot_be_forward_declared):
(headers_for_type):

  • WebKit.xcodeproj/project.pbxproj:
  • WebProcess/Network/NetworkProcessConnection.cpp:

(WebKit::NetworkProcessConnection::didReceiveMessage):

  • WebProcess/WebProcess.cpp:

(WebKit::WebProcess::networkProcessConnectionClosed):
(WebKit::WebProcess::registerStorageAreaMap):
(WebKit::WebProcess::unregisterStorageAreaMap):
(WebKit::WebProcess::storageAreaMap const):

  • WebProcess/WebProcess.h:
  • WebProcess/WebStorage/StorageAreaImpl.cpp:

(WebKit::StorageAreaImpl::prewarm):
(WebKit::StorageAreaImpl::incrementAccessCount): Deleted.
(WebKit::StorageAreaImpl::decrementAccessCount): Deleted.
(WebKit::StorageAreaImpl::closeDatabaseIfIdle): Deleted.

  • WebProcess/WebStorage/StorageAreaImpl.h:
  • WebProcess/WebStorage/StorageAreaMap.cpp:

(WebKit::StorageAreaMap::StorageAreaMap):
(WebKit::StorageAreaMap::~StorageAreaMap):
(WebKit::StorageAreaMap::setItem):
(WebKit::StorageAreaMap::removeItem):
(WebKit::StorageAreaMap::clear):
(WebKit::StorageAreaMap::ensureMap):
(WebKit::StorageAreaMap::dispatchStorageEvent):
(WebKit::StorageAreaMap::clearCache):
(WebKit::StorageAreaMap::sendConnectMessage):
(WebKit::StorageAreaMap::connectSync):
(WebKit::StorageAreaMap::connect):
(WebKit::StorageAreaMap::didConnect):
(WebKit::StorageAreaMap::disconnect):

  • WebProcess/WebStorage/StorageAreaMap.h:
  • WebProcess/WebStorage/StorageAreaMap.messages.in:
  • WebProcess/WebStorage/StorageAreaMapIdentifier.h: Added.
Location:
trunk/Source
Files:
27 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r288291 r288298  
     12022-01-20  Sihui Liu  <sihui_liu@apple.com>
     2
     3        Make LocalStorage prewarming async
     4        https://bugs.webkit.org/show_bug.cgi?id=235236
     5
     6        Reviewed by Chris Dumez.
     7
     8        * page/DOMWindow.cpp:
     9        (WebCore::DOMWindow::prewarmLocalStorageIfNecessary):
     10        * page/Frame.cpp:
     11        (WebCore::Frame::didPrewarmLocalStorage): Deleted.
     12        (WebCore::Frame::mayPrewarmLocalStorage const): Deleted.
     13        * page/Frame.h:
     14        * storage/StorageArea.h:
     15        (WebCore::StorageArea::prewarm):
     16        * storage/StorageType.h:
     17
    1182022-01-20  Alan Bujtas  <zalan@apple.com>
    219
  • trunk/Source/WebCore/page/DOMWindow.cpp

    r287348 r288298  
    414414        return;
    415415
    416     if (!page->mainFrame().mayPrewarmLocalStorage())
    417         return;
    418 
    419416    // This eagerly constructs the StorageArea, which will load items from disk.
    420417    auto localStorageResult = this->localStorage();
     
    426423        return;
    427424
    428     page->mainFrame().didPrewarmLocalStorage();
     425    localStorage->area().prewarm();
    429426}
    430427
  • trunk/Source/WebCore/page/Frame.cpp

    r287110 r288298  
    10581058}
    10591059
    1060 void Frame::didPrewarmLocalStorage()
    1061 {
    1062     ASSERT(isMainFrame());
    1063     ASSERT(m_localStoragePrewarmingCount < maxlocalStoragePrewarmingCount);
    1064     ++m_localStoragePrewarmingCount;
    1065 }
    1066 
    1067 bool Frame::mayPrewarmLocalStorage() const
    1068 {
    1069     ASSERT(isMainFrame());
    1070     return m_localStoragePrewarmingCount < maxlocalStoragePrewarmingCount;
    1071 }
    1072 
    10731060FloatSize Frame::screenSize() const
    10741061{
  • trunk/Source/WebCore/page/Frame.h

    r286825 r288298  
    292292    bool activeDOMObjectsAndAnimationsSuspended() const { return m_activeDOMObjectsAndAnimationsSuspendedCount > 0; }
    293293
    294     void didPrewarmLocalStorage();
    295     bool mayPrewarmLocalStorage() const;
    296 
    297294    enum class InvalidateContentEventRegionsReason { Layout, EventHandlerChange };
    298295    void invalidateContentEventRegionsIfNeeded(InvalidateContentEventRegionsReason);
     
    362359    unsigned m_selfOnlyRefCount { 0 };
    363360    bool m_hasHadUserInteraction { false };
    364     unsigned m_localStoragePrewarmingCount { 0 };
    365361
    366362    FloatSize m_overrideScreenSize;
  • trunk/Source/WebCore/storage/StorageArea.h

    r254859 r288298  
    5959    virtual void decrementAccessCount() { }
    6060    virtual void closeDatabaseIfIdle() { }
     61    virtual void prewarm() { }
    6162};
    6263
  • trunk/Source/WebCore/storage/StorageType.h

    r254859 r288298  
    2626#pragma once
    2727
     28#include <wtf/EnumTraits.h>
     29
    2830namespace WebCore {
    2931
     
    4547
    4648} // namespace WebCore
     49
     50namespace WTF {
     51
     52template<> struct EnumTraits<WebCore::StorageType> {
     53    using values = EnumValues<
     54        WebCore::StorageType,
     55        WebCore::StorageType::Session,
     56        WebCore::StorageType::Local,
     57        WebCore::StorageType::TransientLocal
     58    >;
     59};
     60
     61} // namespace WTF
  • trunk/Source/WebKit/ChangeLog

    r288296 r288298  
     12022-01-20  Sihui Liu  <sihui_liu@apple.com>
     2
     3        Make LocalStorage prewarming async
     4        https://bugs.webkit.org/show_bug.cgi?id=235236
     5
     6        Reviewed by Chris Dumez.
     7
     8        StorageAreaMap in web process needs to sync with a remote StorageArea in network process before it performs any
     9        Web Storage operation. To connect to remote StorageArea, StorageAreaMap currently sends out two sync messages:
     10        1. ConnectTo*StorageArea: for getting the remote StorageAreaIdentifier
     11        2. getValues: for getting the content of StorageArea
     12        We can merge these two messages into one message: ConnectToStorageAreaSync, and return both remote
     13        StorageAreaIdentifier and content in its reply. This way, web process will not be blocked twice.
     14
     15        To reduce the wait time for connecting to a local StorageArea, we would prewarm LocalStorage by creating its
     16        StorageAreaMap ahead and making it connected (r247555), but we don't actually need StorageAreaMap to be ready
     17        for operation at this time. Therefore, a new async message ConnectToStorageArea is added to be used for
     18        prewarming.
     19
     20        If LocalStorage is used immediately after prewarming, a StorageAreaMap may send ConnectToStorageAreaSync before
     21        receiving the reply of ConnectToStorageArea. In this case, StorageAreaMap would handle ConnectToStorageAreaSync
     22        reply before ConnectToStorageArea reply (due to the priority of sync message), and also before other async
     23        messages (DispatchStorageEvent / ClearCache) that are sent from network process earlier before the sync reply.
     24        To solve this, we use a message identifier to indicate the order of messages sent from network process, so
     25        StorageAreaMap can ignore previous messages when it is already synced with a more recent version of StorageArea.
     26
     27        * NetworkProcess/WebStorage/StorageArea.cpp:
     28        (WebKit::StorageArea::clear):
     29        (WebKit::StorageArea::dispatchEvents const):
     30        * NetworkProcess/storage/LocalStorageManager.cpp:
     31        (WebKit::LocalStorageManager::connectToLocalStorageArea):
     32        (WebKit::LocalStorageManager::connectToTransientLocalStorageArea):
     33        * NetworkProcess/storage/LocalStorageManager.h:
     34        * NetworkProcess/storage/NetworkStorageManager.cpp:
     35        (WebKit::NetworkStorageManager::connectToStorageArea):
     36        (WebKit::NetworkStorageManager::connectToStorageAreaSync):
     37        (WebKit::NetworkStorageManager::connectToLocalStorageArea): Deleted.
     38        (WebKit::NetworkStorageManager::connectToTransientLocalStorageArea): Deleted.
     39        (WebKit::NetworkStorageManager::connectToSessionStorageArea): Deleted.
     40        (WebKit::NetworkStorageManager::getValues): Deleted.
     41        * NetworkProcess/storage/NetworkStorageManager.h:
     42        * NetworkProcess/storage/NetworkStorageManager.messages.in:
     43        * NetworkProcess/storage/SessionStorageManager.cpp:
     44        (WebKit::SessionStorageManager::connectToSessionStorageArea):
     45        * NetworkProcess/storage/SessionStorageManager.h:
     46        * NetworkProcess/storage/StorageAreaBase.cpp:
     47        (WebKit::StorageAreaBase::nextMessageIdentifier):
     48        (WebKit::StorageAreaBase::StorageAreaBase):
     49        (WebKit::StorageAreaBase::addListener):
     50        (WebKit::StorageAreaBase::notifyListenersAboutClear):
     51        (WebKit::StorageAreaBase::dispatchEvents const):
     52        * NetworkProcess/storage/StorageAreaBase.h:
     53        * Scripts/webkit/messages.py:
     54        (types_that_cannot_be_forward_declared):
     55        (headers_for_type):
     56        * WebKit.xcodeproj/project.pbxproj:
     57        * WebProcess/Network/NetworkProcessConnection.cpp:
     58        (WebKit::NetworkProcessConnection::didReceiveMessage):
     59        * WebProcess/WebProcess.cpp:
     60        (WebKit::WebProcess::networkProcessConnectionClosed):
     61        (WebKit::WebProcess::registerStorageAreaMap):
     62        (WebKit::WebProcess::unregisterStorageAreaMap):
     63        (WebKit::WebProcess::storageAreaMap const):
     64        * WebProcess/WebProcess.h:
     65        * WebProcess/WebStorage/StorageAreaImpl.cpp:
     66        (WebKit::StorageAreaImpl::prewarm):
     67        (WebKit::StorageAreaImpl::incrementAccessCount): Deleted.
     68        (WebKit::StorageAreaImpl::decrementAccessCount): Deleted.
     69        (WebKit::StorageAreaImpl::closeDatabaseIfIdle): Deleted.
     70        * WebProcess/WebStorage/StorageAreaImpl.h:
     71        * WebProcess/WebStorage/StorageAreaMap.cpp:
     72        (WebKit::StorageAreaMap::StorageAreaMap):
     73        (WebKit::StorageAreaMap::~StorageAreaMap):
     74        (WebKit::StorageAreaMap::setItem):
     75        (WebKit::StorageAreaMap::removeItem):
     76        (WebKit::StorageAreaMap::clear):
     77        (WebKit::StorageAreaMap::ensureMap):
     78        (WebKit::StorageAreaMap::dispatchStorageEvent):
     79        (WebKit::StorageAreaMap::clearCache):
     80        (WebKit::StorageAreaMap::sendConnectMessage):
     81        (WebKit::StorageAreaMap::connectSync):
     82        (WebKit::StorageAreaMap::connect):
     83        (WebKit::StorageAreaMap::didConnect):
     84        (WebKit::StorageAreaMap::disconnect):
     85        * WebProcess/WebStorage/StorageAreaMap.h:
     86        * WebProcess/WebStorage/StorageAreaMap.messages.in:
     87        * WebProcess/WebStorage/StorageAreaMapIdentifier.h: Added.
     88
    1892022-01-20  Youenn Fablet  <youenn@apple.com>
    290
  • trunk/Source/WebKit/NetworkProcess/WebStorage/StorageArea.cpp

    r284142 r288298  
    166166
    167167    for (auto& listenerUniqueID : m_eventListeners)
    168         IPC::Connection::send(listenerUniqueID, Messages::StorageAreaMap::ClearCache(), m_identifier.toUInt64());
     168        IPC::Connection::send(listenerUniqueID, Messages::StorageAreaMap::ClearCache(0), m_identifier.toUInt64());
    169169}
    170170
     
    189189    for (auto& listenerUniqueID : m_eventListeners) {
    190190        auto optionalStorageAreaImplID = listenerUniqueID == sourceConnection ? std::make_optional(storageAreaImplID) : std::nullopt;
    191         IPC::Connection::send(listenerUniqueID, Messages::StorageAreaMap::DispatchStorageEvent(optionalStorageAreaImplID, key, oldValue, newValue, urlString), m_identifier.toUInt64());
     191        IPC::Connection::send(listenerUniqueID, Messages::StorageAreaMap::DispatchStorageEvent(optionalStorageAreaImplID, key, oldValue, newValue, urlString, 0), m_identifier.toUInt64());
    192192    }
    193193}
  • trunk/Source/WebKit/NetworkProcess/storage/LocalStorageManager.cpp

    r286936 r288298  
    166166}
    167167
    168 StorageAreaIdentifier LocalStorageManager::connectToLocalStorageArea(IPC::Connection::UniqueID connection, const WebCore::ClientOrigin& origin, Ref<WorkQueue>&& workQueue)
     168StorageAreaIdentifier LocalStorageManager::connectToLocalStorageArea(IPC::Connection::UniqueID connection, StorageAreaMapIdentifier sourceIdentifier, const WebCore::ClientOrigin& origin, Ref<WorkQueue>&& workQueue)
    169169{
    170170    if (!m_localStorageArea) {
     
    178178
    179179    ASSERT(m_path.isEmpty() || m_localStorageArea->type() == StorageAreaBase::Type::SQLite);
    180     m_localStorageArea->addListener(connection);
     180    m_localStorageArea->addListener(connection, sourceIdentifier);
    181181    return m_localStorageArea->identifier();
    182182}
    183183
    184 StorageAreaIdentifier LocalStorageManager::connectToTransientLocalStorageArea(IPC::Connection::UniqueID connection, const WebCore::ClientOrigin& origin)
     184StorageAreaIdentifier LocalStorageManager::connectToTransientLocalStorageArea(IPC::Connection::UniqueID connection, StorageAreaMapIdentifier sourceIdentifier, const WebCore::ClientOrigin& origin)
    185185{
    186186    if (!m_transientStorageArea) {
     
    190190
    191191    ASSERT(m_transientStorageArea->type() == StorageAreaBase::Type::Memory);
    192     m_transientStorageArea->addListener(connection);
     192    m_transientStorageArea->addListener(connection, sourceIdentifier);
    193193    return m_transientStorageArea->identifier();
    194194}
  • trunk/Source/WebKit/NetworkProcess/storage/LocalStorageManager.h

    r286944 r288298  
    2828#include "Connection.h"
    2929#include "StorageAreaIdentifier.h"
     30#include "StorageAreaMapIdentifier.h"
    3031#include <wtf/WorkQueue.h>
    3132
     
    5758    void connectionClosed(IPC::Connection::UniqueID);
    5859
    59     StorageAreaIdentifier connectToLocalStorageArea(IPC::Connection::UniqueID, const WebCore::ClientOrigin&, Ref<WorkQueue>&&);
    60     StorageAreaIdentifier connectToTransientLocalStorageArea(IPC::Connection::UniqueID, const WebCore::ClientOrigin&);
     60    StorageAreaIdentifier connectToLocalStorageArea(IPC::Connection::UniqueID, StorageAreaMapIdentifier, const WebCore::ClientOrigin&, Ref<WorkQueue>&&);
     61    StorageAreaIdentifier connectToTransientLocalStorageArea(IPC::Connection::UniqueID, StorageAreaMapIdentifier, const WebCore::ClientOrigin&);
    6162    void disconnectFromStorageArea(IPC::Connection::UniqueID, StorageAreaIdentifier);
    6263
  • trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp

    r287731 r288298  
    626626}
    627627
    628 void NetworkStorageManager::connectToLocalStorageArea(IPC::Connection& connection, StorageNamespaceIdentifier, WebCore::SecurityOriginData&& topOrigin, CompletionHandler<void(StorageAreaIdentifier)>&& completionHandler)
    629 {
    630     ASSERT(!RunLoop::isMain());
    631 
    632     WebCore::ClientOrigin origin = { topOrigin, topOrigin };
    633     completionHandler(localOriginStorageManager(origin).localStorageManager(*m_storageAreaRegistry).connectToLocalStorageArea(connection.uniqueID(), origin, m_queue.copyRef()));
    634 }
    635 
    636 void NetworkStorageManager::connectToTransientLocalStorageArea(IPC::Connection& connection, StorageNamespaceIdentifier, WebCore::SecurityOriginData&& topOrigin, WebCore::SecurityOriginData&& openingOrigin, CompletionHandler<void(StorageAreaIdentifier)>&& completionHandler)
    637 {
    638     WebCore::ClientOrigin origin = { topOrigin, openingOrigin };
    639     completionHandler(localOriginStorageManager(origin).localStorageManager(*m_storageAreaRegistry).connectToTransientLocalStorageArea(connection.uniqueID(), origin));
    640 }
    641 
    642 void NetworkStorageManager::connectToSessionStorageArea(IPC::Connection& connection, StorageNamespaceIdentifier identifier, WebCore::SecurityOriginData&& topOrigin, CompletionHandler<void(StorageAreaIdentifier)>&& completionHandler)
    643 {
    644     WebCore::ClientOrigin origin = { topOrigin, topOrigin };
    645     completionHandler(localOriginStorageManager(origin).sessionStorageManager(*m_storageAreaRegistry).connectToSessionStorageArea(connection.uniqueID(), origin, identifier));
     628void NetworkStorageManager::connectToStorageArea(IPC::Connection& connection, WebCore::StorageType type, StorageAreaMapIdentifier sourceIdentifier, StorageNamespaceIdentifier namespaceIdentifier, const WebCore::ClientOrigin& origin, CompletionHandler<void(StorageAreaIdentifier, HashMap<String, String>, uint64_t)>&& completionHandler)
     629{
     630    ASSERT(!RunLoop::isMain());
     631
     632    auto connectionIdentifier = connection.uniqueID();
     633    auto& originStorageManager = localOriginStorageManager(origin);
     634    StorageAreaIdentifier resultIdentifier;
     635    switch (type) {
     636    case WebCore::StorageType::Local:
     637        resultIdentifier = originStorageManager.localStorageManager(*m_storageAreaRegistry).connectToLocalStorageArea(connectionIdentifier, sourceIdentifier, origin, m_queue.copyRef());
     638        break;
     639    case WebCore::StorageType::TransientLocal:
     640        resultIdentifier = originStorageManager.localStorageManager(*m_storageAreaRegistry).connectToTransientLocalStorageArea(connectionIdentifier, sourceIdentifier, origin);
     641        break;
     642    case WebCore::StorageType::Session:
     643        resultIdentifier = originStorageManager.sessionStorageManager(*m_storageAreaRegistry).connectToSessionStorageArea(connectionIdentifier, sourceIdentifier, origin, namespaceIdentifier);
     644    }
     645
     646    if (auto storageArea = m_storageAreaRegistry->getStorageArea(resultIdentifier))
     647        return completionHandler(resultIdentifier, storageArea->allItems(), StorageAreaBase::nextMessageIdentifier());
     648
     649    return completionHandler(resultIdentifier, HashMap<String, String> { }, StorageAreaBase::nextMessageIdentifier());
     650}
     651
     652void NetworkStorageManager::connectToStorageAreaSync(IPC::Connection& connection, WebCore::StorageType type, StorageAreaMapIdentifier sourceIdentifier, StorageNamespaceIdentifier namespaceIdentifier, const WebCore::ClientOrigin& origin, CompletionHandler<void(StorageAreaIdentifier, HashMap<String, String>, uint64_t)>&& completionHandler)
     653{
     654    connectToStorageArea(connection, type, sourceIdentifier, namespaceIdentifier, origin, WTFMove(completionHandler));
    646655}
    647656
     
    668677            sessionStorageManager->cloneStorageArea(connection.uniqueID(), fromIdentifier, toIdentifier);
    669678    }
    670 }
    671 
    672 void NetworkStorageManager::getValues(StorageAreaIdentifier identifier, CompletionHandler<void(const HashMap<String, String>&)>&& completionHandler)
    673 {
    674     ASSERT(!RunLoop::isMain());
    675 
    676     if (auto storageArea = m_storageAreaRegistry->getStorageArea(identifier))
    677         return completionHandler(storageArea->allItems());
    678    
    679     return completionHandler({ });
    680679}
    681680
  • trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h

    r287156 r288298  
    3131#include "StorageAreaIdentifier.h"
    3232#include "StorageAreaImplIdentifier.h"
     33#include "StorageAreaMapIdentifier.h"
    3334#include "StorageNamespaceIdentifier.h"
    3435#include "WebsiteData.h"
     
    4546namespace WebCore {
    4647struct ClientOrigin;
     48enum class StorageType : uint8_t;
    4749}
    4850
     
    109111   
    110112    // Message handlers for WebStorage.
    111     void connectToLocalStorageArea(IPC::Connection&, StorageNamespaceIdentifier, WebCore::SecurityOriginData&&, CompletionHandler<void(StorageAreaIdentifier)>&&);
    112     void connectToTransientLocalStorageArea(IPC::Connection&, StorageNamespaceIdentifier, WebCore::SecurityOriginData&&, WebCore::SecurityOriginData&&, CompletionHandler<void(StorageAreaIdentifier)>&&);
    113     void connectToSessionStorageArea(IPC::Connection&, StorageNamespaceIdentifier, WebCore::SecurityOriginData&&, CompletionHandler<void(StorageAreaIdentifier)>&&);
     113    void connectToStorageArea(IPC::Connection&, WebCore::StorageType, StorageAreaMapIdentifier, StorageNamespaceIdentifier, const WebCore::ClientOrigin&, CompletionHandler<void(StorageAreaIdentifier, HashMap<String, String>, uint64_t)>&&);
     114    void connectToStorageAreaSync(IPC::Connection&, WebCore::StorageType, StorageAreaMapIdentifier, StorageNamespaceIdentifier, const WebCore::ClientOrigin&, CompletionHandler<void(StorageAreaIdentifier, HashMap<String, String>, uint64_t)>&&);
    114115    void disconnectFromStorageArea(IPC::Connection&, StorageAreaIdentifier);
    115116    void cloneSessionStorageNamespace(IPC::Connection&, StorageNamespaceIdentifier, StorageNamespaceIdentifier);
    116     void getValues(StorageAreaIdentifier, CompletionHandler<void(const HashMap<String, String>&)>&&);
    117117    void setItem(IPC::Connection&, StorageAreaIdentifier, StorageAreaImplIdentifier, uint64_t seed, String&& key, String&& value, String&& urlString);
    118118    void removeItem(IPC::Connection&, StorageAreaIdentifier, StorageAreaImplIdentifier, uint64_t seed, String&& key, String&& urlString);
  • trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.messages.in

    r287156 r288298  
    4141    GetHandle(WebCore::FileSystemHandleIdentifier identifier, String name) -> (Expected<std::pair<WebCore::FileSystemHandleIdentifier, bool>, WebKit::FileSystemStorageError> result) Async WantsConnection
    4242
    43     ConnectToLocalStorageArea(WebKit::StorageNamespaceIdentifier storageNamespaceID, struct WebCore::SecurityOriginData securityOriginData) -> (WebKit::StorageAreaIdentifier identifier) Synchronous WantsConnection
    44     ConnectToTransientLocalStorageArea(WebKit::StorageNamespaceIdentifier storageNamespaceID, struct WebCore::SecurityOriginData topLevelSecurityOriginData, struct WebCore::SecurityOriginData securityOriginData) -> (WebKit::StorageAreaIdentifier identifier) Synchronous WantsConnection
    45     ConnectToSessionStorageArea(WebKit::StorageNamespaceIdentifier storageNamespaceID, struct WebCore::SecurityOriginData securityOriginData) -> (WebKit::StorageAreaIdentifier identifier) Synchronous WantsConnection
     43    ConnectToStorageArea(WebCore::StorageType type, WebKit::StorageAreaMapIdentifier sourceIdentifier, WebKit::StorageNamespaceIdentifier namespaceIdentifier, struct WebCore::ClientOrigin origin) -> (WebKit::StorageAreaIdentifier identifier, HashMap<String, String> items, uint64_t messageIdentifier) Async WantsConnection
     44    ConnectToStorageAreaSync(WebCore::StorageType type, WebKit::StorageAreaMapIdentifier sourceIdentifier, WebKit::StorageNamespaceIdentifier namespaceIdentifier, struct WebCore::ClientOrigin origin) -> (WebKit::StorageAreaIdentifier identifier, HashMap<String, String> items, uint64_t messageIdentifier) Synchronous WantsConnection
    4645    DisconnectFromStorageArea(WebKit::StorageAreaIdentifier identifier) WantsConnection
    4746    CloneSessionStorageNamespace(WebKit::StorageNamespaceIdentifier fromStorageNamespaceID, WebKit::StorageNamespaceIdentifier toStorageNamespaceID) WantsConnection
    48     GetValues(WebKit::StorageAreaIdentifier identifier) -> (HashMap<String, String> values) Synchronous
    4947    SetItem(WebKit::StorageAreaIdentifier identifier, WebKit::StorageAreaImplIdentifier implIdentifier, uint64_t storageMapSeed, String key, String value, String urlString) WantsConnection
    5048    RemoveItem(WebKit::StorageAreaIdentifier identifier, WebKit::StorageAreaImplIdentifier implIdentifier, uint64_t storageMapSeed, String key, String urlString) WantsConnection
  • trunk/Source/WebKit/NetworkProcess/storage/SessionStorageManager.cpp

    r287090 r288298  
    7373}
    7474
    75 StorageAreaIdentifier SessionStorageManager::connectToSessionStorageArea(IPC::Connection::UniqueID connection, const WebCore::ClientOrigin& origin, StorageNamespaceIdentifier namespaceIdentifier)
     75StorageAreaIdentifier SessionStorageManager::connectToSessionStorageArea(IPC::Connection::UniqueID connection, StorageAreaMapIdentifier sourceIdentifier, const WebCore::ClientOrigin& origin, StorageNamespaceIdentifier namespaceIdentifier)
    7676{
    7777    auto identifier = m_storageAreasByNamespace.get(namespaceIdentifier);
     
    8585        return StorageAreaIdentifier { };
    8686
    87     storageArea->addListener(connection);
     87    storageArea->addListener(connection, sourceIdentifier);
     88
    8889    return identifier;
    8990}
  • trunk/Source/WebKit/NetworkProcess/storage/SessionStorageManager.h

    r287090 r288298  
    2828#include "Connection.h"
    2929#include "StorageAreaIdentifier.h"
     30#include "StorageAreaMapIdentifier.h"
    3031#include "StorageNamespaceIdentifier.h"
    3132
     
    4849    void connectionClosed(IPC::Connection::UniqueID);
    4950
    50     StorageAreaIdentifier connectToSessionStorageArea(IPC::Connection::UniqueID, const WebCore::ClientOrigin&, StorageNamespaceIdentifier);
     51    StorageAreaIdentifier connectToSessionStorageArea(IPC::Connection::UniqueID, StorageAreaMapIdentifier, const WebCore::ClientOrigin&, StorageNamespaceIdentifier);
    5152    void disconnectFromStorageArea(IPC::Connection::UniqueID, StorageAreaIdentifier);
    5253    void cloneStorageArea(IPC::Connection::UniqueID, StorageNamespaceIdentifier, StorageNamespaceIdentifier);
  • trunk/Source/WebKit/NetworkProcess/storage/StorageAreaBase.cpp

    r286936 r288298  
    3131namespace WebKit {
    3232
     33uint64_t StorageAreaBase::nextMessageIdentifier()
     34{
     35    static std::atomic<uint64_t> currentIdentifier;
     36    return ++currentIdentifier;
     37}
     38
    3339StorageAreaBase::StorageAreaBase(unsigned quota, const WebCore::ClientOrigin& origin)
    34     : m_identifier(StorageAreaIdentifier::generate())
     40    : m_identifier(StorageAreaIdentifier::generateThreadSafe())
    3541    , m_quota(quota)
    3642    , m_origin(origin)
     
    4046StorageAreaBase::~StorageAreaBase() = default;
    4147
    42 void StorageAreaBase::addListener(IPC::Connection::UniqueID connection)
     48void StorageAreaBase::addListener(IPC::Connection::UniqueID connection, StorageAreaMapIdentifier identifier)
    4349{
    44     ASSERT(!m_listeners.contains(connection));
     50    ASSERT(!m_listeners.contains(connection) || m_listeners.get(connection) == identifier);
    4551
    46     m_listeners.add(connection);
     52    m_listeners.add(connection, identifier);
    4753}
    4854
     
    5965void StorageAreaBase::notifyListenersAboutClear()
    6066{
    61     for (auto& connection : m_listeners)
    62         IPC::Connection::send(connection, Messages::StorageAreaMap::ClearCache(), m_identifier.toUInt64());
     67    for (auto& [connection, identifier] : m_listeners)
     68        IPC::Connection::send(connection, Messages::StorageAreaMap::ClearCache(StorageAreaBase::nextMessageIdentifier()), identifier.toUInt64());
    6369}
    6470
     
    6773    ASSERT(sourceImplIdentifier);
    6874
    69     for (auto& connection : m_listeners) {
     75    for (auto& [connection, identifier] : m_listeners) {
    7076        std::optional<StorageAreaImplIdentifier> implIdentifier;
    7177        if (connection == sourceConnection)
    7278            implIdentifier = sourceImplIdentifier;
    73         IPC::Connection::send(connection, Messages::StorageAreaMap::DispatchStorageEvent(implIdentifier, key, oldValue, newValue, urlString), m_identifier.toUInt64());
     79        IPC::Connection::send(connection, Messages::StorageAreaMap::DispatchStorageEvent(implIdentifier, key, oldValue, newValue, urlString, StorageAreaBase::nextMessageIdentifier()), identifier.toUInt64());
    7480    }
    7581}
  • trunk/Source/WebKit/NetworkProcess/storage/StorageAreaBase.h

    r286936 r288298  
    2929#include "StorageAreaIdentifier.h"
    3030#include "StorageAreaImplIdentifier.h"
     31#include "StorageAreaMapIdentifier.h"
    3132#include <WebCore/ClientOrigin.h>
    3233#include <wtf/WeakPtr.h>
     
    4849    WTF_MAKE_FAST_ALLOCATED;
    4950public:
     51    static uint64_t nextMessageIdentifier();
    5052    virtual ~StorageAreaBase();
    5153
     
    6062    WebCore::ClientOrigin origin() const { return m_origin; }
    6163    unsigned quota() const { return m_quota; }
    62     void addListener(IPC::Connection::UniqueID);
     64    void addListener(IPC::Connection::UniqueID, StorageAreaMapIdentifier);
    6365    void removeListener(IPC::Connection::UniqueID);
    6466    bool hasListeners() const;
     
    7880    unsigned m_quota;
    7981    WebCore::ClientOrigin m_origin;
    80     HashSet<IPC::Connection::UniqueID> m_listeners;
     82    HashMap<IPC::Connection::UniqueID, StorageAreaMapIdentifier> m_listeners;
    8183};
    8284
  • trunk/Source/WebKit/Scripts/webkit/messages.py

    r287808 r288298  
    306306        'WebCore::SourceBufferAppendMode',
    307307        'WebCore::SpeechRecognitionConnectionClientIdentifier',
     308        'WebCore::StorageType',
    308309        'WebCore::UserMediaRequestIdentifier',
    309310        'WebCore::WebLockIdentifier',
     
    348349        'WebKit::StorageAreaIdentifier',
    349350        'WebKit::StorageAreaImplIdentifier',
     351        'WebKit::StorageAreaMapIdentifier',
    350352        'WebKit::StorageNamespaceIdentifier',
    351353        'WebKit::TapIdentifier',
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r288293 r288298  
    14591459                93AB9B552575A2760098B10E /* SpeechRecognitionRealtimeMediaSourceManagerMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AB9B4F257589110098B10E /* SpeechRecognitionRealtimeMediaSourceManagerMessageReceiver.cpp */; };
    14601460                93AB9B562575A28B0098B10E /* SpeechRecognitionRemoteRealtimeMediaSourceManagerMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AB9B51257589110098B10E /* SpeechRecognitionRemoteRealtimeMediaSourceManagerMessageReceiver.cpp */; };
     1461                93AEC161278F8CD30066666F /* StorageAreaMapIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 93AEC160278F8CD20066666F /* StorageAreaMapIdentifier.h */; };
    14611462                93B0A67526D5ADCF00AA21E4 /* WebPermissionController.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B0A67426D5A72E00AA21E4 /* WebPermissionController.h */; };
    14621463                93B2614D227D149E00B97A76 /* StorageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B26149227D147200B97A76 /* StorageManager.h */; };
     
    53085309                93AB9B53257589120098B10E /* SpeechRecognitionRemoteRealtimeMediaSourceManagerMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpeechRecognitionRemoteRealtimeMediaSourceManagerMessages.h; sourceTree = "<group>"; };
    53095310                93AB9B54257589120098B10E /* SpeechRecognitionRealtimeMediaSourceManagerMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpeechRecognitionRealtimeMediaSourceManagerMessages.h; sourceTree = "<group>"; };
     5311                93AEC160278F8CD20066666F /* StorageAreaMapIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageAreaMapIdentifier.h; sourceTree = "<group>"; };
    53105312                93B0A67326D5A72E00AA21E4 /* WebPermissionController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebPermissionController.cpp; sourceTree = "<group>"; };
    53115313                93B0A67426D5A72E00AA21E4 /* WebPermissionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPermissionController.h; sourceTree = "<group>"; };
     
    70647066                                1ACECD2317162DB1001FC9EF /* StorageAreaMap.h */,
    70657067                                1A334DEA16DE8B68006A8E38 /* StorageAreaMap.messages.in */,
     7068                                93AEC160278F8CD20066666F /* StorageAreaMapIdentifier.h */,
    70667069                                465F4E05230B2E7C003CEDB7 /* StorageNamespaceIdentifier.h */,
    70677070                                1A17635416B1D5D000D88FD6 /* StorageNamespaceImpl.cpp */,
     
    1326613269                                1AD3306F16B1D991004F60E7 /* StorageAreaImpl.h in Headers */,
    1326713270                                1ACECD2517162DB1001FC9EF /* StorageAreaMap.h in Headers */,
     13271                                93AEC161278F8CD30066666F /* StorageAreaMapIdentifier.h in Headers */,
    1326813272                                1A334DEE16DE8F88006A8E38 /* StorageAreaMapMessages.h in Headers */,
    1326913273                                93E799C7276027460074008A /* StorageAreaRegistry.h in Headers */,
  • trunk/Source/WebKit/WebProcess/Network/NetworkProcessConnection.cpp

    r287021 r288298  
    118118    }
    119119    if (decoder.messageReceiverName() == Messages::StorageAreaMap::messageReceiverName()) {
    120         if (auto* storageAreaMap = WebProcess::singleton().storageAreaMap(makeObjectIdentifier<StorageAreaIdentifierType>(decoder.destinationID())))
     120        if (auto storageAreaMap = WebProcess::singleton().storageAreaMap(makeObjectIdentifier<StorageAreaMapIdentifierType>(decoder.destinationID())))
    121121            storageAreaMap->didReceiveMessage(connection, decoder);
    122122        return;
  • trunk/Source/WebKit/WebProcess/WebProcess.cpp

    r287693 r288298  
    11901190    ASSERT_UNUSED(connection, m_networkProcessConnection == connection);
    11911191
    1192     for (auto* storageAreaMap : copyToVector(m_storageAreaMaps.values()))
    1193         storageAreaMap->disconnect();
     1192    for (auto key : copyToVector(m_storageAreaMaps.keys())) {
     1193        if (auto map = m_storageAreaMaps.get(key))
     1194            map->disconnect();
     1195    }
    11941196
    11951197    for (auto& page : m_pageMap.values()) {
     
    16981700void WebProcess::registerStorageAreaMap(StorageAreaMap& storageAreaMap)
    16991701{
    1700     ASSERT(storageAreaMap.identifier());
    1701     ASSERT(!m_storageAreaMaps.contains(*storageAreaMap.identifier()));
    1702     m_storageAreaMaps.set(*storageAreaMap.identifier(), &storageAreaMap);
     1702    auto identifier = storageAreaMap.identifier();
     1703    ASSERT(!m_storageAreaMaps.contains(identifier));
     1704    m_storageAreaMaps.add(identifier, storageAreaMap);
    17031705}
    17041706
    17051707void WebProcess::unregisterStorageAreaMap(StorageAreaMap& storageAreaMap)
    17061708{
    1707     ASSERT(storageAreaMap.identifier());
    1708     ASSERT(m_storageAreaMaps.contains(*storageAreaMap.identifier()));
    1709     ASSERT(m_storageAreaMaps.get(*storageAreaMap.identifier()) == &storageAreaMap);
    1710     m_storageAreaMaps.remove(*storageAreaMap.identifier());
    1711 }
    1712 
    1713 StorageAreaMap* WebProcess::storageAreaMap(StorageAreaIdentifier identifier) const
     1709    auto identifier = storageAreaMap.identifier();
     1710    ASSERT(m_storageAreaMaps.contains(identifier));
     1711    ASSERT(m_storageAreaMaps.get(identifier).get() == &storageAreaMap);
     1712    m_storageAreaMaps.remove(identifier);
     1713}
     1714
     1715WeakPtr<StorageAreaMap> WebProcess::storageAreaMap(StorageAreaMapIdentifier identifier) const
    17141716{
    17151717    return m_storageAreaMaps.get(identifier);
  • trunk/Source/WebKit/WebProcess/WebProcess.h

    r287876 r288298  
    3131#include "IdentifierTypes.h"
    3232#include "SandboxExtension.h"
    33 #include "StorageAreaIdentifier.h"
     33#include "StorageAreaMapIdentifier.h"
    3434#include "TextCheckerState.h"
    3535#include "UserContentControllerIdentifier.h"
     
    285285    void registerStorageAreaMap(StorageAreaMap&);
    286286    void unregisterStorageAreaMap(StorageAreaMap&);
    287     StorageAreaMap* storageAreaMap(StorageAreaIdentifier) const;
     287    WeakPtr<StorageAreaMap> storageAreaMap(StorageAreaMapIdentifier) const;
    288288
    289289#if PLATFORM(COCOA)
     
    743743#endif
    744744
    745     HashMap<StorageAreaIdentifier, StorageAreaMap*> m_storageAreaMaps;
     745    HashMap<StorageAreaMapIdentifier, WeakPtr<StorageAreaMap>> m_storageAreaMaps;
    746746   
    747747    // Prewarmed WebProcesses do not have an associated sessionID yet, which is why this is an optional.
  • trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.cpp

    r284142 r288298  
    113113}
    114114
    115 void StorageAreaImpl::incrementAccessCount()
     115void StorageAreaImpl::prewarm()
    116116{
    117     // Storage access is handled in the network process, so there's nothing to do here.
    118 }
    119 
    120 void StorageAreaImpl::decrementAccessCount()
    121 {
    122     // Storage access is handled in the network process, so there's nothing to do here.
    123 }
    124 
    125 void StorageAreaImpl::closeDatabaseIfIdle()
    126 {
    127     // FIXME: Implement this.
    128     ASSERT_NOT_REACHED();
     117    if (m_storageAreaMap)
     118        m_storageAreaMap->connect();
    129119}
    130120
  • trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaImpl.h

    r255815 r288298  
    6262    WebCore::StorageType storageType() const override;
    6363    size_t memoryBytesUsedByCache() override;
    64     void incrementAccessCount() override;
    65     void decrementAccessCount() override;
    66     void closeDatabaseIfIdle() override;
     64    void prewarm() final;
    6765
    6866    Identifier m_identifier;
  • trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp

    r286936 r288298  
    5252
    5353StorageAreaMap::StorageAreaMap(StorageNamespaceImpl& storageNamespace, Ref<WebCore::SecurityOrigin>&& securityOrigin)
    54     : m_namespace(storageNamespace)
     54    : m_identifier(StorageAreaMapIdentifier::generate())
     55    , m_namespace(storageNamespace)
    5556    , m_securityOrigin(WTFMove(securityOrigin))
    5657    , m_quotaInBytes(storageNamespace.quotaInBytes())
    5758    , m_type(storageNamespace.storageType())
    5859{
    59     connect();
     60    WebProcess::singleton().registerStorageAreaMap(*this);
    6061}
    6162
     
    6364{
    6465    disconnect();
     66    WebProcess::singleton().unregisterStorageAreaMap(*this);
    6567}
    6668
     
    9698    m_pendingValueChanges.add(key);
    9799
    98     if (m_mapID)
    99         WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::SetItem(*m_mapID, sourceArea->identifier(), m_currentSeed, key, value, sourceFrame->document()->url().string()), 0);
     100    if (m_remoteAreaIdentifier)
     101        WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::SetItem(*m_remoteAreaIdentifier, sourceArea->identifier(), m_currentSeed, key, value, sourceFrame->document()->url().string()), 0);
    100102    else
    101103        RELEASE_LOG_ERROR(Storage, "StorageAreaMap::setItem failed because storage map ID is invalid");
     
    115117    m_pendingValueChanges.add(key);
    116118
    117     if (m_mapID)
    118         WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::RemoveItem(*m_mapID, sourceArea->identifier(), m_currentSeed, key, sourceFrame->document()->url().string()), 0);
     119    if (m_remoteAreaIdentifier)
     120        WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::RemoveItem(*m_remoteAreaIdentifier, sourceArea->identifier(), m_currentSeed, key, sourceFrame->document()->url().string()), 0);
    119121    else
    120122        RELEASE_LOG_ERROR(Storage, "StorageAreaMap::removeItem failed because storage map ID is invalid");
     
    123125void StorageAreaMap::clear(WebCore::Frame* sourceFrame, StorageAreaImpl* sourceArea)
    124126{
    125     connect();
    126 
     127    connectSync();
    127128    resetValues();
    128129
     
    130131    m_map = makeUnique<StorageMap>(m_quotaInBytes);
    131132
    132     if (m_mapID)
    133         WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::Clear(*m_mapID, sourceArea->identifier(), m_currentSeed, sourceFrame->document()->url().string()), 0);
     133    if (m_remoteAreaIdentifier)
     134        WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkStorageManager::Clear(*m_remoteAreaIdentifier, sourceArea->identifier(), m_currentSeed, sourceFrame->document()->url().string()), 0);
    134135    else
    135136        RELEASE_LOG_ERROR(Storage, "StorageAreaMap::clear failed because storage map ID is invalid");
     
    152153StorageMap& StorageAreaMap::ensureMap()
    153154{
    154     connect();
    155 
    156     if (!m_map) {
     155    connectSync();
     156
     157    if (!m_map)
    157158        m_map = makeUnique<StorageMap>(m_quotaInBytes);
    158159
    159         if (m_mapID) {
    160             // We need to use a IPC::UnboundedSynchronousIPCScope to prevent UIProcess hangs in case we receive a synchronous IPC from the UIProcess while we're waiting for a response
    161             // from our StorageManagerSet::GetValues() IPC. This IPC may be very slow because it may need to fetch the values from disk and there may be a lot of data.
    162             IPC::UnboundedSynchronousIPCScope unboundedSynchronousIPCScope;
    163             HashMap<String, String> values;
    164             WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkStorageManager::GetValues(*m_mapID), Messages::StorageManagerSet::GetValues::Reply(values), 0);
    165             m_map->importItems(WTFMove(values));
    166         } else
    167             RELEASE_LOG_ERROR(Storage, "StorageAreaMap::ensureMap failed to load from network process because storage map ID is invalid");
    168     }
    169160    return *m_map;
    170161}
     
    260251}
    261252
    262 void StorageAreaMap::dispatchStorageEvent(const std::optional<StorageAreaImplIdentifier>& storageAreaImplID, const String& key, const String& oldValue, const String& newValue, const String& urlString)
    263 {
     253void StorageAreaMap::dispatchStorageEvent(const std::optional<StorageAreaImplIdentifier>& storageAreaImplID, const String& key, const String& oldValue, const String& newValue, const String& urlString, uint64_t messageIdentifier)
     254{
     255    if (messageIdentifier < m_lastHandledMessageIdentifier)
     256        return;
     257
     258    m_lastHandledMessageIdentifier = messageIdentifier;
    264259    if (!storageAreaImplID) {
    265260        // This storage event originates from another process so we need to apply the change to our storage area map.
     
    273268}
    274269
    275 void StorageAreaMap::clearCache()
    276 {
     270void StorageAreaMap::clearCache(uint64_t messageIdentifier)
     271{
     272    if (messageIdentifier < m_lastHandledMessageIdentifier)
     273        return;
     274
     275    m_lastHandledMessageIdentifier = messageIdentifier;
    277276    resetValues();
    278277}
     
    345344}
    346345
     346void StorageAreaMap::sendConnectMessage(SendMode mode)
     347{
     348    auto& ipcConnection = WebProcess::singleton().ensureNetworkProcessConnection().connection();
     349    auto namespaceIdentifier = m_namespace.storageNamespaceID();
     350    auto originData = m_securityOrigin->data();
     351    auto topOriginData = m_namespace.topLevelOrigin() ? m_namespace.topLevelOrigin()->data() : originData;
     352    auto origin = WebCore::ClientOrigin { topOriginData, originData };
     353    auto type = m_type;
     354    if ((type == StorageType::Local || type == StorageType::TransientLocal) && m_namespace.topLevelOrigin())
     355        type = StorageType::TransientLocal;
     356
     357    if (mode == SendMode::Sync) {
     358        StorageAreaIdentifier remoteAreaIdentifier;
     359        HashMap<String, String> items;
     360        uint64_t messageIdentifier;
     361        ipcConnection.sendSync(Messages::NetworkStorageManager::ConnectToStorageAreaSync(type, m_identifier, namespaceIdentifier, origin), Messages::NetworkStorageManager::ConnectToStorageAreaSync::Reply(remoteAreaIdentifier, items, messageIdentifier), 0);
     362        didConnect(remoteAreaIdentifier, WTFMove(items), messageIdentifier);
     363        return;
     364    }
     365
     366    auto completionHandler = [this, weakThis = WeakPtr { *this }, weakConnection = WeakPtr { ipcConnection }](auto remoteAreaIdentifier, auto items, auto messageIdentifier) mutable {
     367        if (weakThis)
     368            return didConnect(remoteAreaIdentifier, WTFMove(items), messageIdentifier);
     369
     370        if (weakConnection && remoteAreaIdentifier.isValid())
     371            weakConnection->send(Messages::NetworkStorageManager::DisconnectFromStorageArea(remoteAreaIdentifier), 0);
     372    };
     373
     374    ipcConnection.sendWithAsyncReply(Messages::NetworkStorageManager::ConnectToStorageArea(type, m_identifier, namespaceIdentifier, origin), WTFMove(completionHandler));
     375}
     376
     377void StorageAreaMap::connectSync()
     378{
     379    if (m_remoteAreaIdentifier)
     380        return;
     381
     382    sendConnectMessage(SendMode::Sync);
     383}
     384
    347385void StorageAreaMap::connect()
    348386{
    349     if (m_mapID)
    350         return;
    351 
    352     StorageAreaIdentifier mapID;
    353     switch (m_type) {
    354     case StorageType::Local:
    355     case StorageType::TransientLocal:
    356         if (SecurityOrigin* topLevelOrigin = m_namespace.topLevelOrigin())
    357             WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkStorageManager::ConnectToTransientLocalStorageArea(m_namespace.storageNamespaceID(), topLevelOrigin->data(), m_securityOrigin->data()), Messages::NetworkStorageManager::ConnectToTransientLocalStorageArea::Reply(mapID), 0);
    358         else
    359             WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkStorageManager::ConnectToLocalStorageArea(m_namespace.storageNamespaceID(), m_securityOrigin->data()), Messages::NetworkStorageManager::ConnectToLocalStorageArea::Reply(mapID), 0);
    360         break;
    361     case StorageType::Session:
    362         WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkStorageManager::ConnectToSessionStorageArea(m_namespace.storageNamespaceID(), m_securityOrigin->data()), Messages::NetworkStorageManager::ConnectToSessionStorageArea::Reply(mapID), 0);
    363     }
    364 
    365     if (mapID.isValid()) {
    366         m_mapID = mapID;
    367         WebProcess::singleton().registerStorageAreaMap(*this);
    368     }
     387    if (m_remoteAreaIdentifier)
     388        return;
     389
     390    sendConnectMessage(SendMode::Async);
     391}
     392
     393void StorageAreaMap::didConnect(StorageAreaIdentifier remoteAreaIdentifier, HashMap<String, String>&& items, uint64_t messageIdentifier)
     394{
     395    if (messageIdentifier < m_lastHandledMessageIdentifier)
     396        return;
     397
     398    m_lastHandledMessageIdentifier = messageIdentifier;
     399    if (!remoteAreaIdentifier.isValid())
     400        return;
     401
     402    m_remoteAreaIdentifier = remoteAreaIdentifier;
     403    m_map = makeUnique<StorageMap>(m_quotaInBytes);
     404    m_map->importItems(WTFMove(items));
    369405}
    370406
    371407void StorageAreaMap::disconnect()
    372408{
    373     if (!m_mapID)
     409    if (!m_remoteAreaIdentifier)
    374410        return;
    375411
    376412    resetValues();
    377     WebProcess::singleton().unregisterStorageAreaMap(*this);
    378413
    379414    if (auto* networkProcessConnection = WebProcess::singleton().existingNetworkProcessConnection())
    380         networkProcessConnection->connection().send(Messages::NetworkStorageManager::DisconnectFromStorageArea(*m_mapID), 0);
    381 
    382     m_mapID = { };
     415        networkProcessConnection->connection().send(Messages::NetworkStorageManager::DisconnectFromStorageArea(*m_remoteAreaIdentifier), 0);
     416
     417    m_remoteAreaIdentifier = { };
     418    m_lastHandledMessageIdentifier = 0;
    383419}
    384420
  • trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.h

    r278253 r288298  
    2929#include "StorageAreaIdentifier.h"
    3030#include "StorageAreaImplIdentifier.h"
     31#include "StorageAreaMapIdentifier.h"
    3132#include <WebCore/SecurityOrigin.h>
    3233#include <WebCore/StorageArea.h>
     
    6768
    6869    const WebCore::SecurityOrigin& securityOrigin() const { return m_securityOrigin.get(); }
    69     const std::optional<StorageAreaIdentifier>& identifier() const { return m_mapID; }
     70    StorageAreaMapIdentifier identifier() const { return m_identifier; }
    7071
     72    void connect();
    7173    void disconnect();
    7274
     
    7981    void didClear(uint64_t mapSeed);
    8082
    81     void dispatchStorageEvent(const std::optional<StorageAreaImplIdentifier>& sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString);
    82     void clearCache();
     83    void dispatchStorageEvent(const std::optional<StorageAreaImplIdentifier>& sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString, uint64_t messageIdentifier);
     84    void clearCache(uint64_t messageIdentifier);
    8385
    8486    void resetValues();
     
    9193    void dispatchLocalStorageEvent(const std::optional<StorageAreaImplIdentifier>&, const String& key, const String& oldValue, const String& newValue, const String& urlString);
    9294
    93     void connect();
     95    enum class SendMode : bool { Async, Sync };
     96    void sendConnectMessage(SendMode);
     97    void connectSync();
     98    void didConnect(StorageAreaIdentifier, HashMap<String, String>&&, uint64_t messageIdentifier);
    9499
     100    StorageAreaMapIdentifier m_identifier;
     101    uint64_t m_lastHandledMessageIdentifier { 0 };
    95102    StorageNamespaceImpl& m_namespace;
    96103    Ref<WebCore::SecurityOrigin> m_securityOrigin;
    97104    std::unique_ptr<WebCore::StorageMap> m_map;
    98     std::optional<StorageAreaIdentifier> m_mapID;
     105    std::optional<StorageAreaIdentifier> m_remoteAreaIdentifier;
    99106    HashCountedSet<String> m_pendingValueChanges;
    100107    uint64_t m_currentSeed { 0 };
  • trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.messages.in

    r278253 r288298  
    2626    DidClear(uint64_t storageMapSeed)
    2727
    28     DispatchStorageEvent(std::optional<WebKit::StorageAreaImplIdentifier> storageAreaImplID, String key, String oldValue, String newValue, String urlString)
    29     ClearCache()
     28    DispatchStorageEvent(std::optional<WebKit::StorageAreaImplIdentifier> storageAreaImplID, String key, String oldValue, String newValue, String urlString, uint64_t messageIdentifier)
     29    ClearCache(uint64_t messageIdentifier)
    3030}
  • trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMapIdentifier.h

    r288296 r288298  
    11/*
    2  * Copyright (C) 2021 Apple Inc. All rights reserved.
     2 * Copyright (C) 2022 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
    28 #include "Connection.h"
    29 #include "StorageAreaIdentifier.h"
    30 #include "StorageNamespaceIdentifier.h"
    31 
    32 namespace WebCore {
    33 struct ClientOrigin;
    34 } // namespace WebCore
     28#include <wtf/ObjectIdentifier.h>
    3529
    3630namespace WebKit {
    3731
    38 class MemoryStorageArea;
    39 class StorageAreaRegistry;
    40 
    41 class SessionStorageManager {
    42     WTF_MAKE_FAST_ALLOCATED;
    43 public:
    44     explicit SessionStorageManager(StorageAreaRegistry&);
    45     bool isActive() const;
    46     bool hasDataInMemory() const;
    47     void clearData();
    48     void connectionClosed(IPC::Connection::UniqueID);
    49 
    50     StorageAreaIdentifier connectToSessionStorageArea(IPC::Connection::UniqueID, const WebCore::ClientOrigin&, StorageNamespaceIdentifier);
    51     void disconnectFromStorageArea(IPC::Connection::UniqueID, StorageAreaIdentifier);
    52     void cloneStorageArea(IPC::Connection::UniqueID, StorageNamespaceIdentifier, StorageNamespaceIdentifier);
    53 
    54 private:
    55     StorageAreaIdentifier addStorageArea(std::unique_ptr<MemoryStorageArea>, StorageNamespaceIdentifier);
    56 
    57     StorageAreaRegistry& m_registry;
    58     HashMap<StorageAreaIdentifier, std::unique_ptr<MemoryStorageArea>> m_storageAreas;
    59     HashMap<StorageNamespaceIdentifier, StorageAreaIdentifier> m_storageAreasByNamespace;
    60 };
     32enum StorageAreaMapIdentifierType { };
     33using StorageAreaMapIdentifier = ObjectIdentifier<StorageAreaMapIdentifierType>;
    6134
    6235} // namespace WebKit
     36
Note: See TracChangeset for help on using the changeset viewer.