⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 276116 in webkit


Ignore:
Timestamp:
Apr 15, 2021, 10:09:41 PM (5 years ago)
Author:
Russell Epstein
Message:

Cherry-pick r275846. rdar://problem/76727548

Create WebIDBServer only when it is needed
https://bugs.webkit.org/show_bug.cgi?id=224305
rdar://71962196

Reviewed by Alex Christensen.

Currently each WebIDBServer has a separate thread, so we don't want to create or keep WebIDBServer if it's not
in use. There are two cases where network process needs a WebIDBServer:

  1. handle requests from UI process to collect or remove data
  2. handle requests from Web process to perform IDB operations

Previously, we created a WebIDBServer when network process connects to a web process, but that does not mean web
process will perform IDB operations and we may create a thread that's not used. To avoid this, add a new message
AddIDBConnection for web process to ensure network process has WebIDBServer when it's about to perform operation.

Also, previously network process removes a WebIDBServer when session is removed and WebIDBServer is not binded
with any web process connection. Now we remove WebIDBServer when it's done handling requests, that is count of
pending requests from UI process is 0 and WebIDBServer is not binded with web process connection. We also remove
WebIDBServer at when network process is about to be destroyed (NetworkProcess::didClose) so we can break the
reference cycle of NetworkProcess-WebIDBServer-IDBServer, and make sure thread exits.

  • NetworkProcess/IndexedDB/WebIDBServer.cpp: (WebKit::WebIDBServer::create): (WebKit::WebIDBServer::WebIDBServer): (WebKit::m_closeCallback): (WebKit::WebIDBServer::~WebIDBServer): (WebKit::WebIDBServer::getOrigins): (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince): (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins): (WebKit::WebIDBServer::renameOrigin): (WebKit::WebIDBServer::removeConnection): (WebKit::WebIDBServer::close): (WebKit::WebIDBServer::tryClose):
  • NetworkProcess/IndexedDB/WebIDBServer.h:
  • NetworkProcess/NetworkConnectionToWebProcess.cpp: (WebKit::NetworkConnectionToWebProcess::addIDBConnection):
  • NetworkProcess/NetworkConnectionToWebProcess.h:
  • NetworkProcess/NetworkConnectionToWebProcess.messages.in:
  • NetworkProcess/NetworkProcess.cpp: (WebKit::NetworkProcess::didClose): (WebKit::NetworkProcess::createNetworkConnectionToWebProcess): (WebKit::NetworkProcess::destroySession): (WebKit::NetworkProcess::createWebIDBServer): (WebKit::NetworkProcess::connectionToWebProcessClosed): (WebKit::NetworkProcess::removeWebIDBServerIfPossible): Deleted. Move the removal code to WebIDBServer.
  • WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp: (WebKit::WebIDBConnectionToServer::WebIDBConnectionToServer):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275846 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Location:
branches/safari-611-branch/Source/WebKit
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-611-branch/Source/WebKit/ChangeLog

    r276090 r276116  
     12021-04-15  Russell Epstein  <repstein@apple.com>
     2
     3        Cherry-pick r275846. rdar://problem/76727548
     4
     5    Create WebIDBServer only when it is needed
     6    https://bugs.webkit.org/show_bug.cgi?id=224305
     7    rdar://71962196
     8   
     9    Reviewed by Alex Christensen.
     10   
     11    Currently each WebIDBServer has a separate thread, so we don't want to create or keep WebIDBServer if it's not
     12    in use. There are two cases where network process needs a WebIDBServer:
     13    1. handle requests from UI process to collect or remove data
     14    2. handle requests from Web process to perform IDB operations
     15   
     16    Previously, we created a WebIDBServer when network process connects to a web process, but that does not mean web
     17    process will perform IDB operations and we may create a thread that's not used. To avoid this, add a new message
     18    AddIDBConnection for web process to ensure network process has WebIDBServer when it's about to perform operation.
     19   
     20    Also, previously network process removes a WebIDBServer when session is removed and WebIDBServer is not binded
     21    with any web process connection. Now we remove WebIDBServer when it's done handling requests, that is count of
     22    pending requests from UI process is 0 and WebIDBServer is not binded with web process connection. We also remove
     23    WebIDBServer at when network process is about to be destroyed (NetworkProcess::didClose) so we can break the
     24    reference cycle of NetworkProcess-WebIDBServer-IDBServer, and make sure thread exits.
     25   
     26    * NetworkProcess/IndexedDB/WebIDBServer.cpp:
     27    (WebKit::WebIDBServer::create):
     28    (WebKit::WebIDBServer::WebIDBServer):
     29    (WebKit::m_closeCallback):
     30    (WebKit::WebIDBServer::~WebIDBServer):
     31    (WebKit::WebIDBServer::getOrigins):
     32    (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince):
     33    (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins):
     34    (WebKit::WebIDBServer::renameOrigin):
     35    (WebKit::WebIDBServer::removeConnection):
     36    (WebKit::WebIDBServer::close):
     37    (WebKit::WebIDBServer::tryClose):
     38    * NetworkProcess/IndexedDB/WebIDBServer.h:
     39    * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     40    (WebKit::NetworkConnectionToWebProcess::addIDBConnection):
     41    * NetworkProcess/NetworkConnectionToWebProcess.h:
     42    * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
     43    * NetworkProcess/NetworkProcess.cpp:
     44    (WebKit::NetworkProcess::didClose):
     45    (WebKit::NetworkProcess::createNetworkConnectionToWebProcess):
     46    (WebKit::NetworkProcess::destroySession):
     47    (WebKit::NetworkProcess::createWebIDBServer):
     48    (WebKit::NetworkProcess::connectionToWebProcessClosed):
     49    (WebKit::NetworkProcess::removeWebIDBServerIfPossible): Deleted. Move the removal code to WebIDBServer.
     50    * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
     51    (WebKit::WebIDBConnectionToServer::WebIDBConnectionToServer):
     52   
     53    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275846 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     54
     55    2021-04-12  Sihui Liu  <sihui_liu@apple.com>
     56
     57            Create WebIDBServer only when it is needed
     58            https://bugs.webkit.org/show_bug.cgi?id=224305
     59            rdar://71962196
     60
     61            Reviewed by Alex Christensen.
     62
     63            Currently each WebIDBServer has a separate thread, so we don't want to create or keep WebIDBServer if it's not
     64            in use. There are two cases where network process needs a WebIDBServer:
     65            1. handle requests from UI process to collect or remove data
     66            2. handle requests from Web process to perform IDB operations
     67
     68            Previously, we created a WebIDBServer when network process connects to a web process, but that does not mean web
     69            process will perform IDB operations and we may create a thread that's not used. To avoid this, add a new message
     70            AddIDBConnection for web process to ensure network process has WebIDBServer when it's about to perform operation.
     71
     72            Also, previously network process removes a WebIDBServer when session is removed and WebIDBServer is not binded
     73            with any web process connection. Now we remove WebIDBServer when it's done handling requests, that is count of
     74            pending requests from UI process is 0 and WebIDBServer is not binded with web process connection. We also remove
     75            WebIDBServer at when network process is about to be destroyed (NetworkProcess::didClose) so we can break the
     76            reference cycle of NetworkProcess-WebIDBServer-IDBServer, and make sure thread exits.
     77
     78            * NetworkProcess/IndexedDB/WebIDBServer.cpp:
     79            (WebKit::WebIDBServer::create):
     80            (WebKit::WebIDBServer::WebIDBServer):
     81            (WebKit::m_closeCallback):
     82            (WebKit::WebIDBServer::~WebIDBServer):
     83            (WebKit::WebIDBServer::getOrigins):
     84            (WebKit::WebIDBServer::closeAndDeleteDatabasesModifiedSince):
     85            (WebKit::WebIDBServer::closeAndDeleteDatabasesForOrigins):
     86            (WebKit::WebIDBServer::renameOrigin):
     87            (WebKit::WebIDBServer::removeConnection):
     88            (WebKit::WebIDBServer::close):
     89            (WebKit::WebIDBServer::tryClose):
     90            * NetworkProcess/IndexedDB/WebIDBServer.h:
     91            * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     92            (WebKit::NetworkConnectionToWebProcess::addIDBConnection):
     93            * NetworkProcess/NetworkConnectionToWebProcess.h:
     94            * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
     95            * NetworkProcess/NetworkProcess.cpp:
     96            (WebKit::NetworkProcess::didClose):
     97            (WebKit::NetworkProcess::createNetworkConnectionToWebProcess):
     98            (WebKit::NetworkProcess::destroySession):
     99            (WebKit::NetworkProcess::createWebIDBServer):
     100            (WebKit::NetworkProcess::connectionToWebProcessClosed):
     101            (WebKit::NetworkProcess::removeWebIDBServerIfPossible): Deleted. Move the removal code to WebIDBServer.
     102            * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
     103            (WebKit::WebIDBConnectionToServer::WebIDBConnectionToServer):
     104
    11052021-04-15  Russell Epstein  <repstein@apple.com>
    2106
  • branches/safari-611-branch/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.cpp

    r266742 r276116  
    3737namespace WebKit {
    3838
    39 Ref<WebIDBServer> WebIDBServer::create(PAL::SessionID sessionID, const String& directory, WebCore::IDBServer::IDBServer::StorageQuotaManagerSpaceRequester&& spaceRequester)
    40 {
    41     return adoptRef(*new WebIDBServer(sessionID, directory, WTFMove(spaceRequester)));
    42 }
    43 
    44 WebIDBServer::WebIDBServer(PAL::SessionID sessionID, const String& directory, WebCore::IDBServer::IDBServer::StorageQuotaManagerSpaceRequester&& spaceRequester)
     39Ref<WebIDBServer> WebIDBServer::create(PAL::SessionID sessionID, const String& directory, WebCore::IDBServer::IDBServer::StorageQuotaManagerSpaceRequester&& spaceRequester, CompletionHandler<void()>&& closeCallback)
     40{
     41    return adoptRef(*new WebIDBServer(sessionID, directory, WTFMove(spaceRequester), WTFMove(closeCallback)));
     42}
     43
     44WebIDBServer::WebIDBServer(PAL::SessionID sessionID, const String& directory, WebCore::IDBServer::IDBServer::StorageQuotaManagerSpaceRequester&& spaceRequester, CompletionHandler<void()>&& closeCallback)
    4545    : CrossThreadTaskHandler("com.apple.WebKit.IndexedDBServer", WTF::CrossThreadTaskHandler::AutodrainedPoolForRunLoop::Use)
     46    , m_dataTaskCounter([this](RefCounterEvent) { tryClose(); })
     47    , m_closeCallback(WTFMove(closeCallback))
    4648{
    4749    ASSERT(RunLoop::isMain());
     
    5860{
    5961    ASSERT(RunLoop::isMain());
     62    // close() has to be called to make sure thread exits.
     63    ASSERT(!m_closeCallback);
    6064}
    6165
     
    6468    ASSERT(RunLoop::isMain());
    6569
    66     postTask([this, protectedThis = makeRef(*this), callback = WTFMove(callback)]() mutable {
     70    postTask([this, protectedThis = makeRef(*this), callback = WTFMove(callback), token = m_dataTaskCounter.count()]() mutable {
    6771        ASSERT(!RunLoop::isMain());
    6872
    6973        LockHolder locker(m_server->lock());
    70         postTaskReply(CrossThreadTask([callback = WTFMove(callback), origins = crossThreadCopy(m_server->getOrigins())]() mutable {
     74        postTaskReply(CrossThreadTask([callback = WTFMove(callback), token = WTFMove(token), origins = crossThreadCopy(m_server->getOrigins())]() mutable {
    7175            callback(WTFMove(origins));
    7276        }));
     
    7882    ASSERT(RunLoop::isMain());
    7983
    80     postTask([this, protectedThis = makeRef(*this), modificationTime, callback = WTFMove(callback)]() mutable {
     84    postTask([this, protectedThis = makeRef(*this), modificationTime, callback = WTFMove(callback), token = m_dataTaskCounter.count()]() mutable {
    8185        ASSERT(!RunLoop::isMain());
    8286
    8387        LockHolder locker(m_server->lock());
    8488        m_server->closeAndDeleteDatabasesModifiedSince(modificationTime);
    85         postTaskReply(CrossThreadTask([callback = WTFMove(callback)]() mutable {
     89        postTaskReply(CrossThreadTask([callback = WTFMove(callback), token = WTFMove(token)]() mutable {
    8690            callback();
    8791        }));
     
    9397    ASSERT(RunLoop::isMain());
    9498
    95     postTask([this, protectedThis = makeRef(*this), originDatas = originDatas.isolatedCopy(), callback = WTFMove(callback)] () mutable {
     99    postTask([this, protectedThis = makeRef(*this), originDatas = originDatas.isolatedCopy(), callback = WTFMove(callback), token = m_dataTaskCounter.count()] () mutable {
    96100        ASSERT(!RunLoop::isMain());
    97101
    98102        LockHolder locker(m_server->lock());
    99103        m_server->closeAndDeleteDatabasesForOrigins(originDatas);
    100         postTaskReply(CrossThreadTask([callback = WTFMove(callback)]() mutable {
     104        postTaskReply(CrossThreadTask([callback = WTFMove(callback), token = WTFMove(token)]() mutable {
    101105            callback();
    102106        }));
     
    108112    ASSERT(RunLoop::isMain());
    109113
    110     postTask([this, protectedThis = makeRef(*this), oldOrigin = oldOrigin.isolatedCopy(), newOrigin = newOrigin.isolatedCopy(), callback = WTFMove(callback)] () mutable {
     114    postTask([this, protectedThis = makeRef(*this), oldOrigin = oldOrigin.isolatedCopy(), newOrigin = newOrigin.isolatedCopy(), callback = WTFMove(callback), token = m_dataTaskCounter.count()] () mutable {
    111115        ASSERT(!RunLoop::isMain());
    112116
    113117        LockHolder locker(m_server->lock());
    114118        m_server->renameOrigin(oldOrigin, newOrigin);
    115         postTaskReply(CrossThreadTask(WTFMove(callback)));
     119        postTaskReply(CrossThreadTask([callback = WTFMove(callback), token = WTFMove(token)]() mutable {
     120            callback();
     121        }));
    116122    });
    117123}
     
    373379    ASSERT(RunLoop::isMain());
    374380
    375     m_connections.remove(&connection);
    376     connection.removeThreadMessageReceiver(Messages::WebIDBServer::messageReceiverName());
     381    auto* takenConnection = m_connections.take(&connection);
     382    if (!takenConnection)
     383        return;
     384
     385    takenConnection->removeThreadMessageReceiver(Messages::WebIDBServer::messageReceiverName());
    377386    postTask([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID()] {
    378387        auto connection = m_connectionMap.take(connectionID);
     
    383392        m_server->unregisterConnection(connection->connectionToClient());
    384393    });
     394
     395    tryClose();
    385396}
    386397
     
    400411{
    401412    ASSERT(RunLoop::isMain());
     413    if (!m_closeCallback)
     414        return;
    402415
    403416    // Remove the references held by IPC::Connection.
     
    416429        CrossThreadTaskHandler::kill();
    417430    });
     431
     432    m_closeCallback();
     433}
     434
     435void WebIDBServer::tryClose()
     436{
     437    if (!m_connections.isEmpty() || m_dataTaskCounter.value())
     438        return;
     439
     440    close();
    418441}
    419442
  • branches/safari-611-branch/Source/WebKit/NetworkProcess/IndexedDB/WebIDBServer.h

    r268423 r276116  
    3434#include <WebCore/StorageQuotaManager.h>
    3535#include <wtf/CrossThreadTaskHandler.h>
     36#include <wtf/RefCounter.h>
    3637
    3738namespace WebCore {
     
    4647class WebIDBServer final : public CrossThreadTaskHandler, public IPC::Connection::ThreadMessageReceiverRefCounted {
    4748public:
    48     static Ref<WebIDBServer> create(PAL::SessionID, const String& directory, WebCore::IDBServer::IDBServer::StorageQuotaManagerSpaceRequester&&);
     49    static Ref<WebIDBServer> create(PAL::SessionID, const String& directory, WebCore::IDBServer::IDBServer::StorageQuotaManagerSpaceRequester&&, CompletionHandler<void()>&&);
    4950
    5051    void getOrigins(CompletionHandler<void(HashSet<WebCore::SecurityOriginData>&&)>&&);
     
    9192    void close();
    9293
    93     bool hasConnection() const { return !m_connections.isEmpty(); }
    9494private:
    95     WebIDBServer(PAL::SessionID, const String& directory, WebCore::IDBServer::IDBServer::StorageQuotaManagerSpaceRequester&&);
     95    WebIDBServer(PAL::SessionID, const String& directory, WebCore::IDBServer::IDBServer::StorageQuotaManagerSpaceRequester&&, CompletionHandler<void()>&&);
    9696    ~WebIDBServer();
    9797
    9898    void postTask(WTF::Function<void()>&&);
     99
     100    void tryClose();
    99101
    100102    std::unique_ptr<WebCore::IDBServer::IDBServer> m_server;
     
    103105    HashMap<IPC::Connection::UniqueID, std::unique_ptr<WebIDBConnectionToClient>> m_connectionMap;
    104106    HashSet<IPC::Connection*> m_connections;
     107
     108    enum DataTaskCounterType { };
     109    using DataTaskCounter = RefCounter<DataTaskCounterType>;
     110    using DataTaskCounterToken = DataTaskCounter::Token;
     111    DataTaskCounter m_dataTaskCounter;
     112    CompletionHandler<void()> m_closeCallback;
    105113};
    106114
  • branches/safari-611-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp

    r267227 r276116  
    11711171}
    11721172
     1173void NetworkConnectionToWebProcess::addIDBConnection()
     1174{
     1175    m_networkProcess->webIDBServer(m_sessionID).addConnection(m_connection.get(), m_webProcessIdentifier);
     1176}
     1177
    11731178} // namespace WebKit
    11741179
  • branches/safari-611-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h

    r270219 r276116  
    177177    void broadcastConsoleMessage(JSC::MessageSource, JSC::MessageLevel, const String& message);
    178178
     179    void addIDBConnection();
     180
    179181private:
    180182    NetworkConnectionToWebProcess(NetworkProcess&, WebCore::ProcessIdentifier, PAL::SessionID, IPC::Connection::Identifier);
  • branches/safari-611-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in

    r270219 r276116  
    102102    UpdateActivePages(String name, Vector<String> activePagesOrigins, audit_token_t auditToken)
    103103#endif
     104
     105    AddIDBConnection()
    104106}
  • branches/safari-611-branch/Source/WebKit/NetworkProcess/NetworkProcess.cpp

    r275575 r276116  
    268268        platformFlushCookies(networkSession.sessionID(), [callbackAggregator] { });
    269269    });
     270
     271    // Make sure references to NetworkProcess in spaceRequester and closeHandler is removed.
     272    for (auto& server : m_webIDBServers.values())
     273        server->close();
    270274}
    271275
     
    23272331    }
    23282332
    2329     return WebIDBServer::create(sessionID, path, [this, weakThis = makeWeakPtr(this), sessionID](const auto& origin, uint64_t spaceRequested) {
    2330         RefPtr<StorageQuotaManager> storageQuotaManager = weakThis ? this->storageQuotaManager(sessionID, origin) : nullptr;
    2331         return storageQuotaManager ? storageQuotaManager->requestSpaceOnBackgroundThread(spaceRequested) : StorageQuotaManager::Decision::Deny;
    2332     });
     2333    auto spaceRequester = [protectedThis = makeRef(*this), sessionID](const auto& origin, uint64_t spaceRequested) {
     2334        return protectedThis->storageQuotaManager(sessionID, origin)->requestSpaceOnBackgroundThread(spaceRequested);
     2335    };
     2336    auto closeHandler = [protectedThis = makeRef(*this), sessionID]() {
     2337        protectedThis->m_webIDBServers.remove(sessionID);
     2338    };
     2339    return WebIDBServer::create(sessionID, path, WTFMove(spaceRequester), WTFMove(closeHandler));
    23332340}
    23342341
     
    23592366    sessionStorageQuotaManager->setIDBRootPath(idbRootPath);
    23602367}
    2361 
    2362 void NetworkProcess::removeWebIDBServerIfPossible(PAL::SessionID sessionID)
    2363 {
    2364     ASSERT(RunLoop::isMain());
    2365 
    2366     auto iterator = m_webIDBServers.find(sessionID);
    2367     if (iterator == m_webIDBServers.end())
    2368         return;
    2369 
    2370     if (m_networkSessions.contains(sessionID))
    2371         return;
    2372 
    2373     if (iterator->value->hasConnection())
    2374         return;
    2375 
    2376     iterator->value->close();
    2377     m_webIDBServers.remove(iterator);
    2378 }
    2379 
    23802368#endif // ENABLE(INDEXED_DATABASE)
    23812369
     
    26552643    ASSERT(webIDBServer);
    26562644    webIDBServer->removeConnection(connection);
    2657     removeWebIDBServerIfPossible(sessionID);
    26582645#endif
    26592646}
  • branches/safari-611-branch/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp

    r263157 r276116  
    6262    : m_connectionToServer(IDBClient::IDBConnectionToServer::create(*this))
    6363{
     64    send(Messages::NetworkConnectionToWebProcess::AddIDBConnection());
    6465}
    6566
Note: See TracChangeset for help on using the changeset viewer.