Changeset 242580 in webkit


Ignore:
Timestamp:
Mar 6, 2019 4:43:24 PM (5 years ago)
Author:
Chris Dumez
Message:

[iOS] ProcessDidResume() IPC should be sent upon resuming when ProcessWillSuspendImminently() IPC was sent
https://bugs.webkit.org/show_bug.cgi?id=195382
<rdar://problem/48642739>

Reviewed by Geoffrey Garen.

ProcessDidResume() IPC should be sent upon resuming when ProcessWillSuspendImminently() IPC was sent. Previously,
we only send ProcessDidResume() to the WebProcess if PrepareToSuspend() was sent, not when the more urgent
ProcessWillSuspendImminently() IPC was sent.

This mismatch has lead to bugs because the WebProcess does not know it got resumed and failed to unfreeze the
layers it froze upon suspension.

  • UIProcess/ProcessAssertion.h:

(WebKit::ProcessAssertionClient::~ProcessAssertionClient):

  • UIProcess/ProcessThrottler.cpp:

(WebKit::ProcessThrottler::updateAssertion):
(WebKit::ProcessThrottler::uiAssertionWillExpireImminently):
(WebKit::ProcessThrottler::assertionWillExpireImminently): Deleted.

  • UIProcess/ProcessThrottler.h:
  • UIProcess/ios/ProcessAssertionIOS.mm:

(-[WKProcessAssertionBackgroundTaskManager _notifyClientsOfImminentSuspension]):
(WebKit::ProcessAssertion::~ProcessAssertion):
(WebKit::ProcessAndUIAssertion::~ProcessAndUIAssertion):
(WebKit::ProcessAndUIAssertion::setClient):

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::didCompletePageTransition):
Revert change that was landed in r242098 to work around this ProcessThrottler bug.

  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::applicationWillEnterForeground):
Revert change that was landed in r242554 to work around this ProcessThrottler bug.

Location:
trunk/Source/WebKit
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r242579 r242580  
     12019-03-06  Chris Dumez  <cdumez@apple.com>
     2
     3        [iOS] ProcessDidResume() IPC should be sent upon resuming when ProcessWillSuspendImminently() IPC was sent
     4        https://bugs.webkit.org/show_bug.cgi?id=195382
     5        <rdar://problem/48642739>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        ProcessDidResume() IPC should be sent upon resuming when ProcessWillSuspendImminently() IPC was sent. Previously,
     10        we only send ProcessDidResume() to the WebProcess if PrepareToSuspend() was sent, not when the more urgent
     11        ProcessWillSuspendImminently() IPC was sent.
     12
     13        This mismatch has lead to bugs because the WebProcess does not know it got resumed and failed to unfreeze the
     14        layers it froze upon suspension.
     15
     16        * UIProcess/ProcessAssertion.h:
     17        (WebKit::ProcessAssertionClient::~ProcessAssertionClient):
     18
     19        * UIProcess/ProcessThrottler.cpp:
     20        (WebKit::ProcessThrottler::updateAssertion):
     21        (WebKit::ProcessThrottler::uiAssertionWillExpireImminently):
     22        (WebKit::ProcessThrottler::assertionWillExpireImminently): Deleted.
     23
     24        * UIProcess/ProcessThrottler.h:
     25        * UIProcess/ios/ProcessAssertionIOS.mm:
     26        (-[WKProcessAssertionBackgroundTaskManager _notifyClientsOfImminentSuspension]):
     27        (WebKit::ProcessAssertion::~ProcessAssertion):
     28        (WebKit::ProcessAndUIAssertion::~ProcessAndUIAssertion):
     29        (WebKit::ProcessAndUIAssertion::setClient):
     30
     31        * WebProcess/WebPage/WebPage.cpp:
     32        (WebKit::WebPage::didCompletePageTransition):
     33        Revert change that was landed in r242098 to work around this ProcessThrottler bug.
     34
     35        * WebProcess/WebPage/ios/WebPageIOS.mm:
     36        (WebKit::WebPage::applicationWillEnterForeground):
     37        Revert change that was landed in r242554 to work around this ProcessThrottler bug.
     38
    1392019-03-06  Alex Christensen  <achristensen@webkit.org>
    240
  • trunk/Source/WebKit/UIProcess/ProcessAssertion.h

    r241183 r242580  
    5252class ProcessAssertionClient {
    5353public:
    54     virtual ~ProcessAssertionClient() { };
    55     virtual void assertionWillExpireImminently() = 0;
     54    virtual ~ProcessAssertionClient() { }
     55    virtual void uiAssertionWillExpireImminently() = 0;
    5656};
    5757
  • trunk/Source/WebKit/UIProcess/ProcessThrottler.cpp

    r230918 r242580  
    6969void ProcessThrottler::updateAssertion()
    7070{
     71    bool shouldBeRunnable = m_foregroundCounter.value() || m_backgroundCounter.value();
     72
    7173    // If the process is currently runnable but will be suspended then first give it a chance to complete what it was doing
    7274    // and clean up - move it to the background and send it a message to notify. Schedule a timeout so it can't stay running
    7375    // in the background for too long.
    74     if (m_assertion && m_assertion->state() != AssertionState::Suspended && !m_foregroundCounter.value() && !m_backgroundCounter.value()) {
     76    if (m_assertion && m_assertion->state() != AssertionState::Suspended && !shouldBeRunnable) {
    7577        ++m_suspendMessageCount;
    7678        RELEASE_LOG(ProcessSuspension, "%p - ProcessThrottler::updateAssertion() sending PrepareToSuspend IPC", this);
     
    8284    }
    8385
    84     bool shouldBeRunnable = m_foregroundCounter.value() || m_backgroundCounter.value();
     86    if (shouldBeRunnable) {
     87        // If we're currently waiting for the Web process to do suspension cleanup, but no longer need to be suspended, tell the Web process to cancel the cleanup.
     88        if (m_suspendTimer.isActive())
     89            m_process.sendCancelPrepareToSuspend();
    8590
    86     // If we're currently waiting for the Web process to do suspension cleanup, but no longer need to be suspended, tell the Web process to cancel the cleanup.
    87     if (m_suspendTimer.isActive() && shouldBeRunnable)
    88         m_process.sendCancelPrepareToSuspend();
    89    
    90     if (m_assertion && m_assertion->state() == AssertionState::Suspended && shouldBeRunnable)
    91         m_process.sendProcessDidResume();
     91        if ((m_assertion && m_assertion->state() == AssertionState::Suspended) || m_uiAssertionExpired) {
     92            m_process.sendProcessDidResume();
     93            m_uiAssertionExpired = false;
     94        }
     95    }
    9296
    9397    updateAssertionNow();
     
    126130}
    127131
    128 void ProcessThrottler::assertionWillExpireImminently()
     132void ProcessThrottler::uiAssertionWillExpireImminently()
    129133{
    130134    m_process.sendProcessWillSuspendImminently();
     135    m_uiAssertionExpired = true;
    131136}
    132137
  • trunk/Source/WebKit/UIProcess/ProcessThrottler.h

    r222309 r242580  
    6969
    7070    // ProcessAssertionClient
    71     void assertionWillExpireImminently() override;
     71    void uiAssertionWillExpireImminently() override;
    7272
    7373    ProcessThrottlerClient& m_process;
     
    7878    int m_suspendMessageCount { 0 };
    7979    bool m_shouldTakeUIBackgroundAssertion;
     80    bool m_uiAssertionExpired { false };
    8081};
    8182
  • trunk/Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm

    r240990 r242580  
    9999
    100100    for (auto* client : copyToVector(_clients))
    101         client->assertionWillExpireImminently();
     101        client->uiAssertionWillExpireImminently();
    102102}
    103103
     
    209209    m_assertion.get().invalidationHandler = nil;
    210210
    211     if (ProcessAssertionClient* client = this->client())
    212         [[WKProcessAssertionBackgroundTaskManager shared] removeClient:*client];
    213 
    214211    RELEASE_LOG(ProcessSuspension, "%p - ~ProcessAssertion() Releasing process assertion", this);
    215212    [m_assertion invalidate];
     
    260257    if (m_isHoldingBackgroundAssertion)
    261258        [[WKProcessAssertionBackgroundTaskManager shared] decrementNeedsToRunInBackgroundCount];
     259
     260    if (auto* client = this->client())
     261        [[WKProcessAssertionBackgroundTaskManager shared] removeClient:*client];
    262262}
    263263
     
    271271{
    272272    [[WKProcessAssertionBackgroundTaskManager shared] addClient:newClient];
    273     if (ProcessAssertionClient* oldClient = this->client())
     273    if (auto* oldClient = this->client())
    274274        [[WKProcessAssertionBackgroundTaskManager shared] removeClient:*oldClient];
    275275    ProcessAssertion::setClient(newClient);
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r242551 r242580  
    31483148        RELEASE_LOG_ERROR(ProcessSuspension, "%p - WebPage (PageID=%" PRIu64 ") - LayerTreeFreezeReason::ProcessSuspended was set when removing LayerTreeFreezeReason::PageTransition; current reasons are %d",
    31493149            this, m_pageID, m_LayerTreeFreezeReasons.toRaw());
    3150     }
    3151 
    3152     // FIXME: In iOS, we sometimes never unset ProcessSuspended. See <rdar://problem/48154508>.
    3153     unfreezeLayerTree(LayerTreeFreezeReason::ProcessSuspended);
     3150        ASSERT_NOT_REACHED();
     3151    }
     3152
    31543153    RELEASE_LOG_IF_ALLOWED("%p - WebPage - Did complete page transition", this);
    31553154
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r242561 r242580  
    30113011    cancelMarkLayersVolatile();
    30123012
    3013     // FIXME: In iOS, we sometimes never unset ProcessSuspended. See <rdar://problem/48538837>.
    3014     unfreezeLayerTree(LayerTreeFreezeReason::ProcessSuspended);
    30153013    unfreezeLayerTree(LayerTreeFreezeReason::BackgroundApplication);
    30163014
Note: See TracChangeset for help on using the changeset viewer.