Changeset 244112 in webkit


Ignore:
Timestamp:
Apr 10, 2019 9:30:58 AM (5 years ago)
Author:
youenn@apple.com
Message:

Delay initialization of quota users until the first quota request
https://bugs.webkit.org/show_bug.cgi?id=196467

Reviewed by Chris Dumez.

Source/WebCore:

Instead of triggering initialization of each user when being added,
delay initialization until the first call to requestSpace with a non zero task size.
This will make sure we do not load Cache API information in memory or check for
IDB space until actually necessary.

To implement that, move from a HashSet of being initialized users to a HashMap where the key is user and
the value is the user initialization state.

When removing a user, delay the call to processPendingRequest so that a synchronous call to addUser
can be taken into consideration.

This unflakes some Cache API tests as these tests do clear the Cache API and check for the clearing result.
Clearing the caches triggers a removeUser/addUser dance which then triggers initialization of the Caches structure.

Covered by existing tests.

  • storage/StorageQuotaManager.cpp:

(WebCore::StorageQuotaManager::initializeUsersIfNeeded):
(WebCore::StorageQuotaManager::askUserToInitialize):
(WebCore::StorageQuotaManager::addUser):
(WebCore::StorageQuotaManager::requestSpace):

  • storage/StorageQuotaManager.h:

LayoutTests:

Unflake cache storage tests.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r244111 r244112  
     12019-04-10  Youenn Fablet  <youenn@apple.com>
     2
     3        Delay initialization of quota users until the first quota request
     4        https://bugs.webkit.org/show_bug.cgi?id=196467
     5
     6        Reviewed by Chris Dumez.
     7
     8        Unflake cache storage tests.
     9
     10        * TestExpectations:
     11        * platform/mac-wk2/TestExpectations:
     12
    1132019-04-10  Philippe Normand  <pnormand@igalia.com>
    214
  • trunk/LayoutTests/TestExpectations

    r244094 r244112  
    22302230
    22312231webkit.org/b/182928 http/tests/cache-storage/cache-representation.https.html [ Pass Failure ]
    2232 webkit.org/b/193976 http/tests/cache-storage/cache-clearing-origin.https.html [ Pass Failure ]
    22332232
    22342233webkit.org/b/116621 fast/replaced/preferred-widths.html [ Pass Failure ]
  • trunk/LayoutTests/platform/mac-wk2/TestExpectations

    r244061 r244112  
    855855webkit.org/b/184245 http/tests/workers/service/service-worker-cache-api.https.html [ Pass Failure ]
    856856
    857 webkit.org/b/177380 http/tests/cache-storage/cache-records-persistency.https.html [ Pass Failure ]
    858 
    859857webkit.org/b/184937 transitions/opacity-transition-zindex.html [ Skip ]
    860858
     
    926924webkit.org/b/194916 fast/mediastream/MediaStream-video-element.html [ Pass Failure ]
    927925
    928 webkit.org/b/196228 http/tests/cache-storage/cache-clearing-origin.https.html [ Pass Failure ]
    929 
    930926webkit.org/b/195719 fast/events/wheel-event-destroys-overflow.html [ Pass Timeout ]
    931927webkit.org/b/195719 fast/events/wheelevent-mousewheel-interaction.html  [ Pass Timeout ]
  • trunk/Source/WebCore/ChangeLog

    r244111 r244112  
     12019-04-10  Youenn Fablet  <youenn@apple.com>
     2
     3        Delay initialization of quota users until the first quota request
     4        https://bugs.webkit.org/show_bug.cgi?id=196467
     5
     6        Reviewed by Chris Dumez.
     7
     8        Instead of triggering initialization of each user when being added,
     9        delay initialization until the first call to requestSpace with a non zero task size.
     10        This will make sure we do not load Cache API information in memory or check for
     11        IDB space until actually necessary.
     12
     13        To implement that, move from a HashSet of being initialized users to a HashMap where the key is user and
     14        the value is the user initialization state.
     15
     16        When removing a user, delay the call to processPendingRequest so that a synchronous call to addUser
     17        can be taken into consideration.
     18
     19        This unflakes some Cache API tests as these tests do clear the Cache API and check for the clearing result.
     20        Clearing the caches triggers a removeUser/addUser dance which then triggers initialization of the Caches structure.
     21
     22        Covered by existing tests.
     23
     24        * storage/StorageQuotaManager.cpp:
     25        (WebCore::StorageQuotaManager::initializeUsersIfNeeded):
     26        (WebCore::StorageQuotaManager::askUserToInitialize):
     27        (WebCore::StorageQuotaManager::addUser):
     28        (WebCore::StorageQuotaManager::requestSpace):
     29        * storage/StorageQuotaManager.h:
     30
    1312019-04-10  Philippe Normand  <pnormand@igalia.com>
    232
  • trunk/Source/WebCore/storage/StorageQuotaManager.cpp

    r243339 r244112  
    5454}
    5555
    56 void StorageQuotaManager::addUser(StorageQuotaUser& user)
    57 {
    58     ASSERT(!m_pendingInitializationUsers.contains(&user));
    59     ASSERT(!m_users.contains(&user));
    60     m_pendingInitializationUsers.add(&user);
     56void StorageQuotaManager::initializeUsersIfNeeded()
     57{
     58    if (m_pendingInitializationUsers.isEmpty())
     59        return;
     60
     61    Vector<StorageQuotaUser*> usersToInitialize;
     62    for (auto& keyValue : m_pendingInitializationUsers) {
     63        if (keyValue.value == WhenInitializedCalled::No) {
     64            keyValue.value = WhenInitializedCalled::Yes;
     65            usersToInitialize.append(keyValue.key);
     66        }
     67    }
     68    for (auto* user : usersToInitialize) {
     69        if (m_pendingInitializationUsers.contains(user))
     70            askUserToInitialize(*user);
     71    }
     72}
     73
     74void StorageQuotaManager::askUserToInitialize(StorageQuotaUser& user)
     75{
    6176    user.whenInitialized([this, &user, weakThis = makeWeakPtr(this)]() {
    6277        if (!weakThis)
     
    7489}
    7590
     91void StorageQuotaManager::addUser(StorageQuotaUser& user)
     92{
     93    ASSERT(!m_pendingInitializationUsers.contains(&user));
     94    ASSERT(!m_users.contains(&user));
     95    m_pendingInitializationUsers.add(&user, WhenInitializedCalled::No);
     96
     97    if (!m_pendingRequests.isEmpty())
     98        askUserToInitialize(user);
     99}
     100
    76101bool StorageQuotaManager::shouldAskForMoreSpace(uint64_t spaceIncrease) const
    77102{
     
    86111    ASSERT(m_users.contains(&user) || m_pendingInitializationUsers.contains(&user));
    87112    m_users.remove(&user);
    88     if (m_pendingInitializationUsers.remove(&user) && m_pendingInitializationUsers.isEmpty())
    89         processPendingRequests({ }, ShouldDequeueFirstPendingRequest::No);
     113    if (m_pendingInitializationUsers.remove(&user) && m_pendingInitializationUsers.isEmpty()) {
     114        // When being cleared, quota users may remove themselves and add themselves to trigger reinitialization.
     115        // Let's wait for addUser to be called before processing pending requests.
     116        callOnMainThread([this, weakThis = makeWeakPtr(this)] {
     117            if (!weakThis)
     118                return;
     119
     120            if (m_pendingInitializationUsers.isEmpty())
     121                this->processPendingRequests({ }, ShouldDequeueFirstPendingRequest::No);
     122        });
     123    }
    90124}
    91125
    92126void StorageQuotaManager::requestSpace(uint64_t spaceIncrease, RequestCallback&& callback)
    93127{
    94     if (!m_pendingRequests.isEmpty() || !m_pendingInitializationUsers.isEmpty()) {
     128    if (!m_pendingRequests.isEmpty()) {
     129        m_pendingRequests.append({ spaceIncrease, WTFMove(callback) });
     130        return;
     131    }
     132
     133    if (!spaceIncrease) {
     134        callback(Decision::Grant);
     135        return;
     136    }
     137
     138    initializeUsersIfNeeded();
     139
     140    if (!m_pendingInitializationUsers.isEmpty()) {
    95141        m_pendingRequests.append({ spaceIncrease, WTFMove(callback) });
    96142        return;
     
    102148        return;
    103149    }
     150
    104151    callback(Decision::Grant);
    105152}
  • trunk/Source/WebCore/storage/StorageQuotaManager.h

    r243911 r244112  
    2929#include <wtf/CompletionHandler.h>
    3030#include <wtf/Deque.h>
     31#include <wtf/HashMap.h>
    3132#include <wtf/HashSet.h>
    3233#include <wtf/WeakPtr.h>
     
    6768    void askForMoreSpace(uint64_t spaceIncrease);
    6869
     70    void initializeUsersIfNeeded();
     71    void askUserToInitialize(StorageQuotaUser&);
     72
    6973    enum class ShouldDequeueFirstPendingRequest { No, Yes };
    7074    void processPendingRequests(Optional<uint64_t>, ShouldDequeueFirstPendingRequest);
     
    7478    bool m_isWaitingForSpaceIncreaseResponse { false };
    7579    SpaceIncreaseRequester m_spaceIncreaseRequester;
    76     HashSet<const StorageQuotaUser*> m_pendingInitializationUsers;
     80
     81    enum class WhenInitializedCalled { No, Yes };
     82    HashMap<StorageQuotaUser*, WhenInitializedCalled> m_pendingInitializationUsers;
    7783    HashSet<const StorageQuotaUser*> m_users;
    7884
Note: See TracChangeset for help on using the changeset viewer.