Changeset 225850 in webkit


Ignore:
Timestamp:
Dec 13, 2017 10:13:47 AM (6 years ago)
Author:
Chris Dumez
Message:

[iOS] Take process assertion to prevent the service worker process from getting suspended
https://bugs.webkit.org/show_bug.cgi?id=180735

Reviewed by Brady Eidson.

Take process assertion to prevent the service worker process from getting suspended while
it is still needed. We use the same policy as for the network process, meaning that
unsuspended WebContent processes prevent the service worker process from getting suspended.

This patch still does not enable service workers on iOS. The demo at https://mdn.github.io/sw-test/
appears to work. However, things are not working as expected for mobile.twitter.com where I
see the fetches intercepted by the service worker fail when offline for some reason (unrelated
to process suspension).

  • UIProcess/WebProcessPool.cpp:

(WebKit::m_foregroundWebProcessCounter):
(WebKit::m_backgroundWebProcessCounter):
(WebKit::WebProcessPool::ensureNetworkProcess):
(WebKit::WebProcessPool::establishWorkerContextConnectionToStorageProcess):
(WebKit::WebProcessPool::disconnectProcess):
(WebKit::WebProcessPool::updateProcessAssertions):
(WebKit::WebProcessPool::reinstateNetworkProcessAssertionState):

  • UIProcess/WebProcessPool.h:
  • UIProcess/WebProcessProxy.cpp:

(WebKit::WebProcessProxy::didSetAssertionState):

  • UIProcess/WebProcessProxy.h:
Location:
trunk/Source/WebKit
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r225841 r225850  
     12017-12-13  Chris Dumez  <cdumez@apple.com>
     2
     3        [iOS] Take process assertion to prevent the service worker process from getting suspended
     4        https://bugs.webkit.org/show_bug.cgi?id=180735
     5
     6        Reviewed by Brady Eidson.
     7
     8        Take process assertion to prevent the service worker process from getting suspended while
     9        it is still needed. We use the same policy as for the network process, meaning that
     10        unsuspended WebContent processes prevent the service worker process from getting suspended.
     11
     12        This patch still does not enable service workers on iOS. The demo at https://mdn.github.io/sw-test/
     13        appears to work. However, things are not working as expected for mobile.twitter.com where I
     14        see the fetches intercepted by the service worker fail when offline for some reason (unrelated
     15        to process suspension).
     16
     17        * UIProcess/WebProcessPool.cpp:
     18        (WebKit::m_foregroundWebProcessCounter):
     19        (WebKit::m_backgroundWebProcessCounter):
     20        (WebKit::WebProcessPool::ensureNetworkProcess):
     21        (WebKit::WebProcessPool::establishWorkerContextConnectionToStorageProcess):
     22        (WebKit::WebProcessPool::disconnectProcess):
     23        (WebKit::WebProcessPool::updateProcessAssertions):
     24        (WebKit::WebProcessPool::reinstateNetworkProcessAssertionState):
     25        * UIProcess/WebProcessPool.h:
     26        * UIProcess/WebProcessProxy.cpp:
     27        (WebKit::WebProcessProxy::didSetAssertionState):
     28        * UIProcess/WebProcessProxy.h:
     29
    1302017-12-13  Carlos Garcia Campos  <cgarcia@igalia.com>
    231
  • trunk/Source/WebKit/UIProcess/WebProcessPool.cpp

    r225720 r225850  
    235235    , m_hiddenPageThrottlingTimer(RunLoop::main(), this, &WebProcessPool::updateHiddenPageThrottlingAutoIncreaseLimit)
    236236    , m_serviceWorkerProcessTerminationTimer(RunLoop::main(), this, &WebProcessPool::terminateServiceWorkerProcess)
     237#if PLATFORM(IOS)
     238    , m_foregroundWebProcessCounter([this](RefCounterEvent) { updateProcessAssertions(); })
     239    , m_backgroundWebProcessCounter([this](RefCounterEvent) { updateProcessAssertions(); })
     240#endif
    237241{
    238242    if (m_configuration->shouldHaveLegacyDataStore())
     
    487491    if (m_didNetworkProcessCrash) {
    488492        m_didNetworkProcessCrash = false;
    489         for (auto& process : m_processes)
    490             process->reinstateNetworkProcessAssertionState(*m_networkProcess);
     493        reinstateNetworkProcessAssertionState(*m_networkProcess);
    491494        if (m_websiteDataStore)
    492495            m_websiteDataStore->websiteDataStore().networkProcessDidCrash();
     
    599602    auto serviceWorkerProcessProxy = ServiceWorkerProcessProxy::create(*this, m_websiteDataStore->websiteDataStore());
    600603    m_serviceWorkerProcess = serviceWorkerProcessProxy.ptr();
     604    updateProcessAssertions();
    601605    initializeNewWebProcess(serviceWorkerProcessProxy.get(), m_websiteDataStore->websiteDataStore());
    602606    m_processes.append(WTFMove(serviceWorkerProcessProxy));
     
    924928        m_processWithPageCache = nullptr;
    925929#if ENABLE(SERVICE_WORKER)
    926     if (m_serviceWorkerProcess == process)
     930    if (m_serviceWorkerProcess == process) {
    927931        m_serviceWorkerProcess = nullptr;
     932        updateProcessAssertions();
     933    }
    928934#endif
    929935
     
    17461752}
    17471753
     1754void WebProcessPool::updateProcessAssertions()
     1755{
     1756#if PLATFORM(IOS)
     1757#if ENABLE(SERVICE_WORKER)
     1758    auto updateServiceWorkerProcessAssertion = [&] {
     1759        if (m_serviceWorkerProcess && m_foregroundWebProcessCounter.value()) {
     1760            if (!m_foregroundTokenForServiceWorkerProcess)
     1761                m_foregroundTokenForServiceWorkerProcess = m_serviceWorkerProcess->throttler().foregroundActivityToken();
     1762            m_backgroundTokenForServiceWorkerProcess = nullptr;
     1763            return;
     1764        }
     1765        if (m_serviceWorkerProcess && m_backgroundWebProcessCounter.value()) {
     1766            if (!m_backgroundTokenForServiceWorkerProcess)
     1767                m_backgroundTokenForServiceWorkerProcess = m_serviceWorkerProcess->throttler().backgroundActivityToken();
     1768            m_foregroundTokenForServiceWorkerProcess = nullptr;
     1769            return;
     1770        }
     1771        m_foregroundTokenForServiceWorkerProcess = nullptr;
     1772        m_backgroundTokenForServiceWorkerProcess = nullptr;
     1773    };
     1774    updateServiceWorkerProcessAssertion();
     1775#endif
     1776
     1777    auto updateNetworkProcessAssertion = [&] {
     1778        if (m_foregroundWebProcessCounter.value()) {
     1779            if (!m_foregroundTokenForNetworkProcess)
     1780                m_foregroundTokenForNetworkProcess = ensureNetworkProcess().throttler().foregroundActivityToken();
     1781            m_backgroundTokenForNetworkProcess = nullptr;
     1782            return;
     1783        }
     1784        if (m_backgroundWebProcessCounter.value()) {
     1785            if (!m_backgroundTokenForNetworkProcess)
     1786                m_backgroundTokenForNetworkProcess = ensureNetworkProcess().throttler().backgroundActivityToken();
     1787            m_foregroundTokenForNetworkProcess = nullptr;
     1788            return;
     1789        }
     1790        m_foregroundTokenForNetworkProcess = nullptr;
     1791        m_backgroundTokenForNetworkProcess = nullptr;
     1792    };
     1793    updateNetworkProcessAssertion();
     1794#endif
     1795}
     1796
     1797void WebProcessPool::reinstateNetworkProcessAssertionState(NetworkProcessProxy& newNetworkProcessProxy)
     1798{
     1799#if PLATFORM(IOS)
     1800    // The network process crashed; take new tokens for the new network process.
     1801    if (m_backgroundTokenForNetworkProcess)
     1802        m_backgroundTokenForNetworkProcess = newNetworkProcessProxy.throttler().backgroundActivityToken();
     1803    else if (m_foregroundTokenForNetworkProcess)
     1804        m_foregroundTokenForNetworkProcess = newNetworkProcessProxy.throttler().foregroundActivityToken();
     1805#else
     1806    UNUSED_PARAM(newNetworkProcessProxy);
     1807#endif
     1808}
     1809
    17481810} // namespace WebKit
  • trunk/Source/WebKit/UIProcess/WebProcessPool.h

    r225716 r225850  
    426426    static void unregisterProcessPoolCreationListener(uint64_t identifier);
    427427
     428#if PLATFORM(IOS)
     429    ForegroundWebProcessToken foregroundWebProcessToken() const { return ForegroundWebProcessToken(m_foregroundWebProcessCounter.count()); }
     430    BackgroundWebProcessToken backgroundWebProcessToken() const { return BackgroundWebProcessToken(m_backgroundWebProcessCounter.count()); }
     431#endif
     432
    428433private:
    429434    void platformInitialize();
     
    451456    void processStoppedUsingGamepads(WebProcessProxy&);
    452457#endif
     458
     459    void reinstateNetworkProcessAssertionState(NetworkProcessProxy&);
     460    void updateProcessAssertions();
    453461
    454462    // IPC::MessageReceiver.
     
    638646    HashMap<PAL::SessionID, HashSet<WebPageProxy*>> m_sessionToPagesMap;
    639647    RunLoop::Timer<WebProcessPool> m_serviceWorkerProcessTerminationTimer;
     648
     649#if PLATFORM(IOS)
     650    ForegroundWebProcessCounter m_foregroundWebProcessCounter;
     651    BackgroundWebProcessCounter m_backgroundWebProcessCounter;
     652    ProcessThrottler::ForegroundActivityToken m_foregroundTokenForNetworkProcess;
     653    ProcessThrottler::BackgroundActivityToken m_backgroundTokenForNetworkProcess;
     654#if ENABLE(SERVICE_WORKER)
     655    ProcessThrottler::ForegroundActivityToken m_foregroundTokenForServiceWorkerProcess;
     656    ProcessThrottler::BackgroundActivityToken m_backgroundTokenForServiceWorkerProcess;
     657#endif
     658#endif
    640659};
    641660
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp

    r225553 r225850  
    10581058}
    10591059
    1060 void WebProcessProxy::reinstateNetworkProcessAssertionState(NetworkProcessProxy& newNetworkProcessProxy)
     1060void WebProcessProxy::didSetAssertionState(AssertionState state)
    10611061{
    10621062#if PLATFORM(IOS)
    1063     ASSERT(!m_backgroundTokenForNetworkProcess || !m_foregroundTokenForNetworkProcess);
    1064 
    1065     // The network process crashed; take new tokens for the new network process.
    1066     if (m_backgroundTokenForNetworkProcess)
    1067         m_backgroundTokenForNetworkProcess = newNetworkProcessProxy.throttler().backgroundActivityToken();
    1068     else if (m_foregroundTokenForNetworkProcess)
    1069         m_foregroundTokenForNetworkProcess = newNetworkProcessProxy.throttler().foregroundActivityToken();
    1070 #else
    1071     UNUSED_PARAM(newNetworkProcessProxy);
    1072 #endif
    1073 }
    1074 
    1075 void WebProcessProxy::didSetAssertionState(AssertionState state)
    1076 {
    1077 #if PLATFORM(IOS)
    1078     ASSERT(!m_backgroundTokenForNetworkProcess || !m_foregroundTokenForNetworkProcess);
     1063    if (isServiceWorkerProcess())
     1064        return;
     1065
     1066    ASSERT(!m_backgroundToken || !m_foregroundToken);
    10791067
    10801068    switch (state) {
    10811069    case AssertionState::Suspended:
    10821070        RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::didSetAssertionState(Suspended) release all assertions for network process", this);
    1083         m_foregroundTokenForNetworkProcess = nullptr;
    1084         m_backgroundTokenForNetworkProcess = nullptr;
     1071        m_foregroundToken = nullptr;
     1072        m_backgroundToken = nullptr;
    10851073        for (auto& page : m_pageMap.values())
    10861074            page->processWillBecomeSuspended();
     
    10891077    case AssertionState::Background:
    10901078        RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::didSetAssertionState(Background) taking background assertion for network process", this);
    1091         m_backgroundTokenForNetworkProcess = processPool().ensureNetworkProcess().throttler().backgroundActivityToken();
    1092         m_foregroundTokenForNetworkProcess = nullptr;
     1079        m_backgroundToken = processPool().backgroundWebProcessToken();
     1080        m_foregroundToken = nullptr;
    10931081        break;
    10941082   
    10951083    case AssertionState::Foreground:
    10961084        RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::didSetAssertionState(Foreground) taking foreground assertion for network process", this);
    1097         m_foregroundTokenForNetworkProcess = processPool().ensureNetworkProcess().throttler().foregroundActivityToken();
    1098         m_backgroundTokenForNetworkProcess = nullptr;
     1085        m_foregroundToken = processPool().foregroundWebProcessToken();
     1086        m_backgroundToken = nullptr;
    10991087        for (auto& page : m_pageMap.values())
    11001088            page->processWillBecomeForeground();
     
    11021090    }
    11031091
    1104     ASSERT(!m_backgroundTokenForNetworkProcess || !m_foregroundTokenForNetworkProcess);
     1092    ASSERT(!m_backgroundToken || !m_foregroundToken);
    11051093#else
    11061094    UNUSED_PARAM(state);
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.h

    r225289 r225850  
    7878struct WebsiteData;
    7979
     80#if PLATFORM(IOS)
     81enum ForegroundWebProcessCounterType { };
     82typedef RefCounter<ForegroundWebProcessCounterType> ForegroundWebProcessCounter;
     83typedef ForegroundWebProcessCounter::Token ForegroundWebProcessToken;
     84enum BackgroundWebProcessCounterType { };
     85typedef RefCounter<BackgroundWebProcessCounterType> BackgroundWebProcessCounter;
     86typedef BackgroundWebProcessCounter::Token BackgroundWebProcessToken;
     87#endif
     88
    8089class WebProcessProxy : public ChildProcessProxy, public ResponsivenessTimer::Client, private ProcessThrottlerClient {
    8190public:
     
    175184    ProcessThrottler& throttler() { return m_throttler; }
    176185
    177     void reinstateNetworkProcessAssertionState(NetworkProcessProxy&);
    178 
    179186    void isResponsive(WTF::Function<void(bool isWebProcessResponsive)>&&);
    180187    void didReceiveMainThreadPing();
     
    281288    ProcessThrottler::BackgroundActivityToken m_tokenForHoldingLockedFiles;
    282289#if PLATFORM(IOS)
    283     ProcessThrottler::ForegroundActivityToken m_foregroundTokenForNetworkProcess;
    284     ProcessThrottler::BackgroundActivityToken m_backgroundTokenForNetworkProcess;
     290    ForegroundWebProcessToken m_foregroundToken;
     291    BackgroundWebProcessToken m_backgroundToken;
    285292#endif
    286293
Note: See TracChangeset for help on using the changeset viewer.