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

Changeset 244097 in webkit


Ignore:
Timestamp:
Apr 9, 2019, 4:37:17 PM (7 years ago)
Author:
youenn@apple.com
Message:

Close service worker database on network process suspension
https://bugs.webkit.org/show_bug.cgi?id=196623
<rdar://problem/48930869>

Reviewed by Alex Christensen.

Source/WebCore:

Add suspend/resume support to SWServer.
On suspend, close the service worker database and stop pushing for changes.
On resume, push changes if needed.

  • workers/service/server/RegistrationDatabase.cpp:

(WebCore::RegistrationDatabase::close):

  • workers/service/server/RegistrationDatabase.h:

(WebCore::RegistrationDatabase::isClosed const): Deleted.

  • workers/service/server/RegistrationStore.cpp:

(WebCore::RegistrationStore::closeDatabase):

  • workers/service/server/RegistrationStore.cpp:

(WebCore::RegistrationStore::pushChangesToDatabase):
(WebCore::RegistrationStore::clearAll):
(WebCore::RegistrationStore::startSuspension):
(WebCore::RegistrationStore::endSuspension):

  • workers/service/server/RegistrationStore.h:
  • workers/service/server/SWServer.cpp:

(WebCore::SWServer::startSuspension):
(WebCore::SWServer::endSuspension):

  • workers/service/server/SWServer.h:

Source/WebKit:

Close service worker database when preparing to suspend.
On resume, push changes if any is needed.

  • NetworkProcess/NetworkProcess.cpp:

(WebKit::NetworkProcess::actualPrepareToSuspend):
(WebKit::NetworkProcess::cancelPrepareToSuspend):
(WebKit::NetworkProcess::processDidResume):

  • UIProcess/API/Cocoa/WKProcessPool.mm:

(-[WKProcessPool _sendNetworkProcessWillSuspendImminently]):
(-[WKProcessPool _sendNetworkProcessDidResume]):

  • UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
  • UIProcess/Network/NetworkProcessProxy.h:
  • UIProcess/WebProcessPool.cpp:

(WebKit::WebProcessPool::sendNetworkProcessWillSuspendImminently):
(WebKit::WebProcessPool::sendNetworkProcessDidResume):

  • UIProcess/WebProcessPool.h:

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
Location:
trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r244093 r244097  
     12019-04-09  Youenn Fablet  <youenn@apple.com>
     2
     3        Close service worker database on network process suspension
     4        https://bugs.webkit.org/show_bug.cgi?id=196623
     5        <rdar://problem/48930869>
     6
     7        Reviewed by Alex Christensen.
     8
     9        Add suspend/resume support to SWServer.
     10        On suspend, close the service worker database and stop pushing for changes.
     11        On resume, push changes if needed.
     12
     13        * workers/service/server/RegistrationDatabase.cpp:
     14        (WebCore::RegistrationDatabase::close):
     15        * workers/service/server/RegistrationDatabase.h:
     16        (WebCore::RegistrationDatabase::isClosed const): Deleted.
     17        * workers/service/server/RegistrationStore.cpp:
     18        (WebCore::RegistrationStore::closeDatabase):
     19        * workers/service/server/RegistrationStore.cpp:
     20        (WebCore::RegistrationStore::pushChangesToDatabase):
     21        (WebCore::RegistrationStore::clearAll):
     22        (WebCore::RegistrationStore::startSuspension):
     23        (WebCore::RegistrationStore::endSuspension):
     24        * workers/service/server/RegistrationStore.h:
     25        * workers/service/server/SWServer.cpp:
     26        (WebCore::SWServer::startSuspension):
     27        (WebCore::SWServer::endSuspension):
     28        * workers/service/server/SWServer.h:
     29
    1302019-04-09  Justin Fan  <justin_fan@apple.com>
    231
  • trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp

    r241820 r244097  
    119119void RegistrationDatabase::postTaskToWorkQueue(Function<void()>&& task)
    120120{
     121    ASSERT(isMainThread());
     122
    121123    m_workQueue->dispatch([protectedThis = makeRef(*this), task = WTFMove(task)]() mutable {
    122124        task();
     
    280282            return;
    281283
     284        callOnMainThread(WTFMove(completionHandler));
     285    });
     286}
     287
     288void RegistrationDatabase::close(CompletionHandler<void()>&& completionHandler)
     289{
     290    postTaskToWorkQueue([this, completionHandler = WTFMove(completionHandler)]() mutable {
     291        m_database = nullptr;
    282292        callOnMainThread(WTFMove(completionHandler));
    283293    });
  • trunk/Source/WebCore/workers/service/server/RegistrationDatabase.h

    r232891 r244097  
    5353    ~RegistrationDatabase();
    5454
    55     bool isClosed() const { return !m_database; }
    5655
    5756    void pushChanges(Vector<ServiceWorkerContextData>&&, CompletionHandler<void()>&&);
    5857    void clearAll(CompletionHandler<void()>&&);
     58    void close(CompletionHandler<void()>&&);
    5959
    6060private:
  • trunk/Source/WebCore/workers/service/server/RegistrationStore.cpp

    r232891 r244097  
    5353void RegistrationStore::pushChangesToDatabase(WTF::CompletionHandler<void()>&& completionHandler)
    5454{
     55    if (m_isSuspended) {
     56        m_needsPushingChanges = true;
     57        return;
     58    }
     59
    5560    Vector<ServiceWorkerContextData> changesToPush;
    5661    changesToPush.reserveInitialCapacity(m_updatedRegistrations.size());
     
    6469void RegistrationStore::clearAll(WTF::CompletionHandler<void()>&& completionHandler)
    6570{
     71    m_needsPushingChanges = false;
    6672    m_updatedRegistrations.clear();
    6773    m_databasePushTimer.stop();
     
    7783    }
    7884    completionHandler();
     85}
     86
     87void RegistrationStore::startSuspension(WTF::CompletionHandler<void()>&& completionHandler)
     88{
     89    m_isSuspended = true;
     90    m_database->close(WTFMove(completionHandler));
     91}
     92
     93void RegistrationStore::endSuspension()
     94{
     95    m_isSuspended = false;
     96    if (m_needsPushingChanges)
     97        scheduleDatabasePushIfNecessary();
    7998}
    8099
  • trunk/Source/WebCore/workers/service/server/RegistrationStore.h

    r232874 r244097  
    5252    void flushChanges(WTF::CompletionHandler<void()>&&);
    5353
     54    void startSuspension(WTF::CompletionHandler<void()>&&);
     55    void endSuspension();
     56
    5457    // Callbacks from the SWServer
    5558    void updateRegistration(const ServiceWorkerContextData&);
     
    7376    HashMap<ServiceWorkerRegistrationKey, ServiceWorkerContextData> m_updatedRegistrations;
    7477    Timer m_databasePushTimer;
     78
     79    bool m_isSuspended { false };
     80    bool m_needsPushingChanges { false };
    7581};
    7682
  • trunk/Source/WebCore/workers/service/server/SWServer.cpp

    r242905 r244097  
    211211}
    212212
     213void SWServer::startSuspension(CompletionHandler<void()>&& completionHandler)
     214{
     215    if (m_registrationStore)
     216        m_registrationStore->startSuspension(WTFMove(completionHandler));
     217}
     218
     219void SWServer::endSuspension()
     220{
     221    if (m_registrationStore)
     222        m_registrationStore->endSuspension();
     223}
     224
    213225void SWServer::clear(const SecurityOriginData& securityOrigin, CompletionHandler<void()>&& completionHandler)
    214226{
  • trunk/Source/WebCore/workers/service/server/SWServer.h

    r242905 r244097  
    123123    WEBCORE_EXPORT void clear(const SecurityOriginData&, WTF::CompletionHandler<void()>&&);
    124124
     125    WEBCORE_EXPORT void startSuspension(CompletionHandler<void()>&&);
     126    WEBCORE_EXPORT void endSuspension();
     127
    125128    SWServerRegistration* getRegistration(const ServiceWorkerRegistrationKey&);
    126129    void addRegistration(std::unique_ptr<SWServerRegistration>&&);
  • trunk/Source/WebKit/ChangeLog

    r244096 r244097  
     12019-04-09  Youenn Fablet  <youenn@apple.com>
     2
     3        Close service worker database on network process suspension
     4        https://bugs.webkit.org/show_bug.cgi?id=196623
     5        <rdar://problem/48930869>
     6
     7        Reviewed by Alex Christensen.
     8
     9        Close service worker database when preparing to suspend.
     10        On resume, push changes if any is needed.
     11
     12        * NetworkProcess/NetworkProcess.cpp:
     13        (WebKit::NetworkProcess::actualPrepareToSuspend):
     14        (WebKit::NetworkProcess::cancelPrepareToSuspend):
     15        (WebKit::NetworkProcess::processDidResume):
     16        * UIProcess/API/Cocoa/WKProcessPool.mm:
     17        (-[WKProcessPool _sendNetworkProcessWillSuspendImminently]):
     18        (-[WKProcessPool _sendNetworkProcessDidResume]):
     19        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
     20        * UIProcess/Network/NetworkProcessProxy.h:
     21        * UIProcess/WebProcessPool.cpp:
     22        (WebKit::WebProcessPool::sendNetworkProcessWillSuspendImminently):
     23        (WebKit::WebProcessPool::sendNetworkProcessDidResume):
     24        * UIProcess/WebProcessPool.h:
     25
    1262019-04-09  Daniel Bates  <dabates@apple.com>
    227
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp

    r244077 r244097  
    19841984    for (auto& connection : m_webProcessConnections)
    19851985        connection->cleanupForSuspension([delayedTaskCounter] { });
     1986
     1987    for (auto& server : m_swServers.values())
     1988        server->startSuspension([delayedTaskCounter] { });
    19861989}
    19871990
     
    20052008    // or NetworkProcessProxy::DidCancelProcessSuspension- message, but not both.
    20062009    RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::cancelPrepareToSuspend()", this);
     2010    resume();
     2011}
     2012
     2013void NetworkProcess::applicationDidEnterBackground()
     2014{
     2015    m_downloadManager.applicationDidEnterBackground();
     2016}
     2017
     2018void NetworkProcess::applicationWillEnterForeground()
     2019{
     2020    m_downloadManager.applicationWillEnterForeground();
     2021}
     2022
     2023void NetworkProcess::processDidResume()
     2024{
     2025    RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::processDidResume()", this);
     2026    resume();
     2027}
     2028
     2029void NetworkProcess::resume()
     2030{
    20072031    platformProcessDidResume();
    20082032    for (auto& connection : m_webProcessConnections)
    20092033        connection->endSuspension();
    2010 }
    2011 
    2012 void NetworkProcess::applicationDidEnterBackground()
    2013 {
    2014     m_downloadManager.applicationDidEnterBackground();
    2015 }
    2016 
    2017 void NetworkProcess::applicationWillEnterForeground()
    2018 {
    2019     m_downloadManager.applicationWillEnterForeground();
    2020 }
    2021 
    2022 void NetworkProcess::processDidResume()
    2023 {
    2024     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcess::processDidResume()", this);
    2025     platformProcessDidResume();
    2026     for (auto& connection : m_webProcessConnections)
    2027         connection->endSuspension();
     2034
     2035    for (auto& server : m_swServers.values())
     2036        server->endSuspension();
    20282037}
    20292038
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.h

    r244077 r244097  
    182182    void cancelPrepareToSuspend();
    183183    void processDidResume();
     184    void resume();
    184185
    185186    // Diagnostic messages logging.
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm

    r243711 r244097  
    426426}
    427427
     428- (void)_sendNetworkProcessWillSuspendImminently
     429{
     430    _processPool->sendNetworkProcessWillSuspendImminently();
     431}
     432
     433- (void)_sendNetworkProcessDidResume
     434{
     435    _processPool->sendNetworkProcessDidResume();
     436}
     437
    428438- (void)_terminateServiceWorkerProcesses
    429439{
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h

    r243711 r244097  
    8484
    8585// Test only. Should be called only while no web content processes are running.
    86 - (void)_terminateNetworkProcess;
     86- (void)_terminateNetworkProcess WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     87- (void)_sendNetworkProcessWillSuspendImminently WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     88- (void)_sendNetworkProcessDidResume WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    8789- (void)_terminateServiceWorkerProcesses WK_API_AVAILABLE(macos(10.14), ios(12.0));
    8890- (void)_disableServiceWorkerProcessTerminationDelay WK_API_AVAILABLE(macos(10.14), ios(12.0));
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h

    r244077 r244097  
    184184#endif
    185185
     186    // ProcessThrottlerClient
     187    void sendProcessWillSuspendImminently() final;
     188    void sendProcessDidResume() final;
     189
    186190private:
    187191    // AuxiliaryProcessProxy
     
    194198
    195199    // ProcessThrottlerClient
    196     void sendProcessWillSuspendImminently() override;
    197     void sendPrepareToSuspend() override;
    198     void sendCancelPrepareToSuspend() override;
    199     void sendProcessDidResume() override;
    200     void didSetAssertionState(AssertionState) override;
     200    void sendPrepareToSuspend() final;
     201    void sendCancelPrepareToSuspend() final;
     202    void didSetAssertionState(AssertionState) final;
    201203
    202204    // IPC::Connection::Client
  • trunk/Source/WebKit/UIProcess/WebProcessPool.cpp

    r244075 r244097  
    17501750}
    17511751
     1752void WebProcessPool::sendNetworkProcessWillSuspendImminently()
     1753{
     1754    if (m_networkProcess)
     1755        m_networkProcess->sendProcessWillSuspendImminently();
     1756}
     1757
     1758void WebProcessPool::sendNetworkProcessDidResume()
     1759{
     1760    if (m_networkProcess)
     1761        m_networkProcess->sendProcessDidResume();
     1762}
     1763
    17521764void WebProcessPool::terminateServiceWorkerProcesses()
    17531765{
  • trunk/Source/WebKit/UIProcess/WebProcessPool.h

    r243877 r244097  
    296296    void clearCachedCredentials();
    297297    void terminateNetworkProcess();
     298    void sendNetworkProcessWillSuspendImminently();
     299    void sendNetworkProcessDidResume();
    298300    void terminateServiceWorkerProcesses();
    299301    void disableServiceWorkerProcessTerminationDelay();
  • trunk/Tools/ChangeLog

    r244096 r244097  
     12019-04-09  Youenn Fablet  <youenn@apple.com>
     2
     3        Close service worker database on network process suspension
     4        https://bugs.webkit.org/show_bug.cgi?id=196623
     5        <rdar://problem/48930869>
     6
     7        Reviewed by Alex Christensen.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
     10
    1112019-04-09  Daniel Bates  <dabates@apple.com>
    212
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm

    r243814 r244097  
    17351735    }
    17361736}
     1737
     1738TEST(ServiceWorkers, SuspendNetworkProcess)
     1739{
     1740    [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
     1741
     1742    // Start with a clean slate data store
     1743    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
     1744        done = true;
     1745    }];
     1746    TestWebKitAPI::Util::run(&done);
     1747    done = false;
     1748
     1749    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     1750
     1751    RetainPtr<SWMessageHandler> messageHandler = adoptNS([[SWMessageHandler alloc] init]);
     1752    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
     1753
     1754    RetainPtr<SWSchemes> handler = adoptNS([[SWSchemes alloc] init]);
     1755    handler->resources.set("sw://host/main.html", ResourceInfo { @"text/html", mainBytes });
     1756    handler->resources.set("sw://host/sw.js", ResourceInfo { @"application/javascript", scriptBytes });
     1757    [configuration setURLSchemeHandler:handler.get() forURLScheme:@"SW"];
     1758
     1759    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     1760    [webView.get().configuration.processPool _registerURLSchemeServiceWorkersCanHandle:@"sw"];
     1761
     1762    auto delegate = adoptNS([[TestSWAsyncNavigationDelegate alloc] init]);
     1763    [webView setNavigationDelegate:delegate.get()];
     1764    [webView setUIDelegate:delegate.get()];
     1765
     1766    done = false;
     1767
     1768    // Normal load to get SW registered.
     1769    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"sw://host/main.html"]];
     1770    [webView loadRequest:request];
     1771
     1772    TestWebKitAPI::Util::run(&done);
     1773    done = false;
     1774
     1775    auto store = [configuration websiteDataStore];
     1776    auto path = store._serviceWorkerRegistrationDirectory;
     1777
     1778    NSURL* directory = [NSURL fileURLWithPath:path isDirectory:YES];
     1779    NSURL *swDBPath = [directory URLByAppendingPathComponent:@"ServiceWorkerRegistrations-4.sqlite3"];
     1780
     1781    EXPECT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:swDBPath.path]);
     1782
     1783    [ webView.get().configuration.processPool _sendNetworkProcessWillSuspendImminently];
     1784
     1785    EXPECT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:swDBPath.path]);
     1786
     1787    [ webView.get().configuration.processPool _sendNetworkProcessDidResume];
     1788
     1789    [webView loadRequest:request];
     1790    TestWebKitAPI::Util::run(&done);
     1791    done = false;
     1792
     1793    EXPECT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:swDBPath.path]);
     1794}
Note: See TracChangeset for help on using the changeset viewer.