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

Changeset 204070 in webkit


Ignore:
Timestamp:
Aug 2, 2016, 11:15:59 PM (10 years ago)
Author:
bshafiei@apple.com
Message:

Merge r204057. rdar://problem/27534205

Location:
branches/safari-602-branch/Source/WebKit2
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-602-branch/Source/WebKit2/ChangeLog

    r203970 r204070  
     12016-08-02  Babak Shafiei  <bshafiei@apple.com>
     2
     3        Merge r204057. rdar://problem/27534205
     4
     5    2016-08-02  Tim Horton  <timothy_horton@apple.com>
     6
     7            REGRESSION (r203385): Frequent RELEASE_ASSERT in WebKit::RemoteLayerTreeDrawingArea::flushLayers()
     8            https://bugs.webkit.org/show_bug.cgi?id=160481
     9            <rdar://problem/27534205>
     10
     11            Reviewed by Simon Fraser.
     12
     13            * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h:
     14            * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm:
     15            (WebKit::RemoteLayerTreeDrawingAreaProxy::commitLayerTree):
     16            (WebKit::RemoteLayerTreeDrawingAreaProxy::didRefreshDisplay):
     17            (WebKit::RemoteLayerTreeDrawingAreaProxy::waitForDidUpdateViewState):
     18            If the UI process sends a didUpdate message while the Web process is in
     19            the middle of flushing on a background thread, the drawing area will
     20            allow another commit to start on the main thread, which then (rightfully)
     21            causes the RELEASE_ASSERT.
     22
     23            This is normally not a problem, because didRefreshDisplay (which sends the didUpdate)
     24            bails if m_didUpdateMessageState is anything other than NotSent, and m_didUpdateMessageState
     25            is only NotSent if the Web process has sent a commit (and thus will not commit again until
     26            it gets a didUpdate). This is the fundamental mechanism that avoids multiple commits being
     27            in flight at once.
     28
     29            In r203385, I added a path where didRefreshDisplay could be called
     30            before the first commit arrived (by way of
     31            _applicationWillEnterForeground -> viewStateDidChange -> waitForDidUpdateViewState).
     32
     33            This caused trouble because m_didUpdateMessageState is initialized to NotSent,
     34            which means that we could end up sending a didUpdate immediately, before the first
     35            commit arrives - even worse, while the first commit is being flushed on a background thread,
     36            leading the aforementioned RELEASE_ASSERT to fire.
     37
     38            Instead, initialize it to Sent (which I've renamed to DoesNotNeedDidUpdate), so that
     39            we won't send a didUpdate until after the first commit arrives (at which point
     40            the two processes are in agreement about the order of things).
     41
     42            It's not currently possible to API test this for multiple reasons, though it is fairly
     43            easy to write a test app that reproduces reliably (by simulating suspend/resume notifications
     44            inside the didFinishNavigation: callback).
     45
    1462016-07-31  Babak Shafiei  <bshafiei@apple.com>
    247
  • branches/safari-602-branch/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h

    r202291 r204070  
    9292    RemoteLayerTreeHost m_remoteLayerTreeHost;
    9393    bool m_isWaitingForDidUpdateGeometry { false };
    94     enum DidUpdateMessageState { NotSent, Sent, MissedCommit };
    95     DidUpdateMessageState m_didUpdateMessageState { NotSent };
     94    enum DidUpdateMessageState { DoesNotNeedDidUpdate, NeedsDidUpdate, MissedCommit };
     95    DidUpdateMessageState m_didUpdateMessageState { DoesNotNeedDidUpdate };
    9696
    9797    WebCore::IntSize m_lastSentSize;
  • branches/safari-602-branch/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm

    r203558 r204070  
    228228
    229229#if PLATFORM(IOS)
    230     if (std::exchange(m_didUpdateMessageState, NotSent) == MissedCommit)
     230    if (std::exchange(m_didUpdateMessageState, NeedsDidUpdate) == MissedCommit)
    231231        didRefreshDisplay(monotonicallyIncreasingTime());
    232232    [m_displayLinkHandler schedule];
    233233#else
    234     m_didUpdateMessageState = NotSent;
     234    m_didUpdateMessageState = NeedsDidUpdate;
    235235    didRefreshDisplay(monotonicallyIncreasingTime());
    236236#endif
     
    400400        return;
    401401
    402     if (m_didUpdateMessageState != NotSent) {
     402    if (m_didUpdateMessageState != NeedsDidUpdate) {
    403403        m_didUpdateMessageState = MissedCommit;
    404404#if PLATFORM(IOS)
     
    408408    }
    409409   
    410     m_didUpdateMessageState = Sent;
     410    m_didUpdateMessageState = DoesNotNeedDidUpdate;
    411411
    412412    TraceScope tracingScope(RAFDidRefreshDisplayStart, RAFDidRefreshDisplayEnd);
     
    426426    // We must send the didUpdate message before blocking on the next commit, otherwise
    427427    // we can be guaranteed that the next commit won't come until after the waitForAndDispatchImmediately times out.
    428     if (m_didUpdateMessageState != Sent)
     428    if (m_didUpdateMessageState != DoesNotNeedDidUpdate)
    429429        didRefreshDisplay(monotonicallyIncreasingTime());
    430430
Note: See TracChangeset for help on using the changeset viewer.