Skip to content

Commit

Permalink
Cherry-pick f4ce577. rdar://121185956
Browse files Browse the repository at this point in the history
    hideContentUntilPendingUpdate async IPC call during backgrounding blocks process suspension
    https://bugs.webkit.org/show_bug.cgi?id=268799
    rdar://121185956

    Reviewed by Chris Dumez.

    On iOS, when the UIProcess goes into the background, it eventually calls in to
    hideContentUntilPendingUpdate through this call stack:

    ```
    WebKit::RemoteLayerTreeDrawingAreaProxy::hideContentUntilPendingUpdate()
    WebKit::WebPageProxy::applicationDidFinishSnapshottingAfterEnteringBackground()
    WebKit::ApplicationStateTracker::didCompleteSnapshotSequence()
    ```

    The problem is that we recently added an async `DrawingArea::DispatchAfterEnsuringDrawing` IPC with
    reply handler call to hideContentUntilPendingUpdate (see 269776@main, 270672@main, 271260@main). An
    async IPC with a reply handler in the UIProcess implicitly takes out a background activity which
    prevents the WebContent process (and also the UIProcess) from suspending until the reply handler
    runs. Unfortunately, since the WebContent process is in the background, presumably it doesn't
    render, so the DispatchAfterEnsuringDrawing reply handler doesn't run, and the background activity
    also never completes. We basically end up blocking process suspension entirely until the 15 second
    timer in ProcessStateMonitor expires and forcefully invalidates all background activities for all
    processes.

    We need to fix this by reworking the logic somehow or by making this DispatchAfterEnsuringDrawing
    IPC not create a background activity. Here I'm just trying to make the IPC call not start a
    background activity.

    Note that there's also a DispatchAfterEnsuringDrawing call in WebPageProxy that I didn't touch since
    I don't have evidence that it's causing a background power regression, but I wonder if that also
    should avoid creating a background activity.

    * Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeDrawingAreaProxy.mm:
    (WebKit::RemoteLayerTreeDrawingAreaProxy::hideContentUntilPendingUpdate):

    Canonical link: https://commits.webkit.org/274157@main

Identifier: 272448.533@safari-7618.1.15.11-branch
  • Loading branch information
bnham authored and rjepstein committed Feb 8, 2024
1 parent 1678e84 commit f8a07d3
Showing 1 changed file with 4 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#import "LayerProperties.h"
#import "Logging.h"
#import "MessageSenderInlines.h"
#import "ProcessThrottler.h"
#import "RemoteLayerTreeDrawingAreaProxyMessages.h"
#import "RemotePageDrawingAreaProxy.h"
#import "RemotePageProxy.h"
Expand Down Expand Up @@ -572,7 +573,9 @@

void RemoteLayerTreeDrawingAreaProxy::hideContentUntilPendingUpdate()
{
m_replyForUnhidingContent = sendWithAsyncReply(Messages::DrawingArea::DispatchAfterEnsuringDrawing(), [] { });
// FIXME(rdar://122365213): Rethink whether this needs to use an async reply handler or start a background activity.
auto activity = m_webProcessProxy->throttler().backgroundActivity("hideContentUntilPendingUpdate"_s);
m_replyForUnhidingContent = m_webProcessProxy->sendWithAsyncReply(Messages::DrawingArea::DispatchAfterEnsuringDrawing(), [timedActivity = makeUnique<ProcessThrottlerTimedActivity>(1_s, WTFMove(activity))] () mutable { }, messageSenderDestinationID(), { }, WebProcessProxy::ShouldStartProcessThrottlerActivity::No);
m_remoteLayerTreeHost->detachRootLayer();
}

Expand Down

0 comments on commit f8a07d3

Please sign in to comment.