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

Changeset 247868 in webkit


Ignore:
Timestamp:
Jul 26, 2019, 11:27:28 AM (7 years ago)
Author:
Chris Dumez
Message:

[iOS] WebPage::TouchEventSync() & WebPage::GetPositionInformation() sync IPC causes UIProcess hangs
https://bugs.webkit.org/show_bug.cgi?id=200138
<rdar://problem/52698157>

Reviewed by Geoffrey Garen.

Source/WebKit:

Revert most of r247822 and use an alternative approach to address hangs. In this patch, the proposal
is to add a SendSyncOption::ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply flag on the
WebPage::TouchEventSync() & WebPage::GetPositionInformation() sendSync() calls in the UIProcess.
Those will cause this IPCs to get dispatched right away in the WebContent process, even if the
WebContent process is itself currently stuck on unbounded (i.e. potentially slow) synchronous IPC
(JS alerts / prompts & sync XHR). Because re-entering WebCore on sync IPC is generally unsafe, this
patch also updates the WebPage::getPositionInformation() & WebPage::touchEventSync() to return early
(i.e. cancelled) if they get called while the WebContent process is stuck on a slow sendSync.

This approach should address the UIProcess hangs caused by the WebPage::TouchEventSync() and
WebPage::GetPositionInformation() sync IPC messages when the WebContent process is busy on a slow XHR
or a JS prompt / alert. It should be safe because we do not re-enter WebCore. The only drawback is that
those IPCs will be cancelled (early return with default value) when the WebContent process is busy.
However, I am being told that this is likely acceptable in practice.

  • Platform/IPC/Connection.cpp:

(IPC::Connection::SyncMessageState::processIncomingMessage):
(IPC::Connection::sendMessage):
(IPC::Connection::sendSyncMessage):
(IPC::Connection::dispatchMessage):

  • Platform/IPC/Connection.h:

(IPC::UnboundedSynchronousIPCScope::UnboundedSynchronousIPCScope):
(IPC::UnboundedSynchronousIPCScope::~UnboundedSynchronousIPCScope):
(IPC::UnboundedSynchronousIPCScope::hasOngoingUnboundedSyncIPC):

  • Platform/IPC/Decoder.cpp:

(IPC::Decoder::shouldDispatchMessageWhenWaitingForSyncReply const):

  • Platform/IPC/Decoder.h:
  • Platform/IPC/Encoder.cpp:

(IPC::Encoder::shouldDispatchMessageWhenWaitingForSyncReply const):
(IPC::Encoder::setShouldDispatchMessageWhenWaitingForSyncReply):
(IPC::Encoder::wrapForTesting):

  • Platform/IPC/Encoder.h:
  • Platform/IPC/MessageFlags.h:
  • UIProcess/Network/NetworkProcessProxy.cpp:

(WebKit::NetworkProcessProxy::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::handleTouchEventSynchronously):

  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView ensurePositionInformationIsUpToDate:]):

  • WebProcess/Network/WebLoaderStrategy.cpp:

(WebKit::WebLoaderStrategy::loadResourceSynchronously):

  • WebProcess/WebCoreSupport/WebChromeClient.cpp:

(WebKit::WebChromeClient::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
(WebKit::WebChromeClient::runJavaScriptAlert):
(WebKit::WebChromeClient::runJavaScriptConfirm):
(WebKit::WebChromeClient::runJavaScriptPrompt):

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::layerVolatilityTimerFired):
(WebKit::WebPage::markLayersVolatile):
(WebKit::WebPage::cancelMarkLayersVolatile):
(WebKit::WebPage::touchEventSync):
(WebKit::WebPage::didCompletePageTransition):
(WebKit::WebPage::updatePreferences):
(WebKit::WebPage::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):

  • WebProcess/WebPage/WebPage.h:

(WebKit::WebPage::sendSyncWithDelayedReply):

  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::getPositionInformation):

LayoutTests:

Update existing layout test accordingly.

  • fast/misc/{testProcessIncomingSyncMessagesWhenWaitingForUnboundedReply-expected.txt: Renamed from LayoutTests/fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply-expected.txt.
  • fast/misc/{testProcessIncomingSyncMessagesWhenWaitingForUnboundedReply.html: Renamed from LayoutTests/fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html.
Location:
trunk
Files:
17 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r247866 r247868  
     12019-07-26  Chris Dumez  <cdumez@apple.com>
     2
     3        [iOS] WebPage::TouchEventSync() & WebPage::GetPositionInformation() sync IPC causes UIProcess hangs
     4        https://bugs.webkit.org/show_bug.cgi?id=200138
     5        <rdar://problem/52698157>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Update existing layout test accordingly.
     10
     11        * fast/misc/{testProcessIncomingSyncMessagesWhenWaitingForUnboundedReply-expected.txt: Renamed from LayoutTests/fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply-expected.txt.
     12        * fast/misc/{testProcessIncomingSyncMessagesWhenWaitingForUnboundedReply.html: Renamed from LayoutTests/fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html.
     13
    1142019-07-26  Zalan Bujtas  <zalan@apple.com>
    215
  • trunk/LayoutTests/fast/misc/{testProcessIncomingSyncMessagesWhenWaitingForUnboundedReply-expected.txt

    r247867 r247868  
    1 Test for the SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply sendSync flag
     1Test for the SendSyncOption::ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply sendSync flag
    22
    33On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
  • trunk/LayoutTests/fast/misc/{testProcessIncomingSyncMessagesWhenWaitingForUnboundedReply.html

    r247867 r247868  
    44<script src="../../resources/js-test.js"></script>
    55<script>
    6 description("Test for the SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply sendSync flag");
     6description("Test for the SendSyncOption::ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply sendSync flag");
    77
    88shouldBeTrue("internals.testProcessIncomingSyncMessagesWhenWaitingForSyncReply()");
  • trunk/Source/WebKit/ChangeLog

    r247866 r247868  
     12019-07-26  Chris Dumez  <cdumez@apple.com>
     2
     3        [iOS] WebPage::TouchEventSync() & WebPage::GetPositionInformation() sync IPC causes UIProcess hangs
     4        https://bugs.webkit.org/show_bug.cgi?id=200138
     5        <rdar://problem/52698157>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Revert most of r247822 and use an alternative approach to address hangs. In this patch, the proposal
     10        is to add a SendSyncOption::ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply flag on the
     11        WebPage::TouchEventSync() & WebPage::GetPositionInformation() sendSync() calls in the UIProcess.
     12        Those will cause this IPCs to get dispatched right away in the WebContent process, even if the
     13        WebContent process is itself currently stuck on unbounded (i.e. potentially slow) synchronous IPC
     14        (JS alerts / prompts & sync XHR). Because re-entering WebCore on sync IPC is generally unsafe, this
     15        patch also updates the WebPage::getPositionInformation() & WebPage::touchEventSync() to return early
     16        (i.e. cancelled) if they get called while the WebContent process is stuck on a slow sendSync.
     17
     18        This approach should address the UIProcess hangs caused by the WebPage::TouchEventSync() and
     19        WebPage::GetPositionInformation() sync IPC messages when the WebContent process is busy on a slow XHR
     20        or a JS prompt / alert. It should be safe because we do not re-enter WebCore. The only drawback is that
     21        those IPCs will be cancelled (early return with default value) when the WebContent process is busy.
     22        However, I am being told that this is likely acceptable in practice.       
     23
     24        * Platform/IPC/Connection.cpp:
     25        (IPC::Connection::SyncMessageState::processIncomingMessage):
     26        (IPC::Connection::sendMessage):
     27        (IPC::Connection::sendSyncMessage):
     28        (IPC::Connection::dispatchMessage):
     29        * Platform/IPC/Connection.h:
     30        (IPC::UnboundedSynchronousIPCScope::UnboundedSynchronousIPCScope):
     31        (IPC::UnboundedSynchronousIPCScope::~UnboundedSynchronousIPCScope):
     32        (IPC::UnboundedSynchronousIPCScope::hasOngoingUnboundedSyncIPC):
     33        * Platform/IPC/Decoder.cpp:
     34        (IPC::Decoder::shouldDispatchMessageWhenWaitingForSyncReply const):
     35        * Platform/IPC/Decoder.h:
     36        * Platform/IPC/Encoder.cpp:
     37        (IPC::Encoder::shouldDispatchMessageWhenWaitingForSyncReply const):
     38        (IPC::Encoder::setShouldDispatchMessageWhenWaitingForSyncReply):
     39        (IPC::Encoder::wrapForTesting):
     40        * Platform/IPC/Encoder.h:
     41        * Platform/IPC/MessageFlags.h:
     42        * UIProcess/Network/NetworkProcessProxy.cpp:
     43        (WebKit::NetworkProcessProxy::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     44        * UIProcess/WebPageProxy.cpp:
     45        (WebKit::WebPageProxy::handleTouchEventSynchronously):
     46        * UIProcess/ios/WKContentViewInteraction.mm:
     47        (-[WKContentView ensurePositionInformationIsUpToDate:]):
     48        * WebProcess/Network/WebLoaderStrategy.cpp:
     49        (WebKit::WebLoaderStrategy::loadResourceSynchronously):
     50        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     51        (WebKit::WebChromeClient::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     52        (WebKit::WebChromeClient::runJavaScriptAlert):
     53        (WebKit::WebChromeClient::runJavaScriptConfirm):
     54        (WebKit::WebChromeClient::runJavaScriptPrompt):
     55        * WebProcess/WebPage/WebPage.cpp:
     56        (WebKit::WebPage::layerVolatilityTimerFired):
     57        (WebKit::WebPage::markLayersVolatile):
     58        (WebKit::WebPage::cancelMarkLayersVolatile):
     59        (WebKit::WebPage::touchEventSync):
     60        (WebKit::WebPage::didCompletePageTransition):
     61        (WebKit::WebPage::updatePreferences):
     62        (WebKit::WebPage::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     63        * WebProcess/WebPage/WebPage.h:
     64        (WebKit::WebPage::sendSyncWithDelayedReply):
     65        * WebProcess/WebPage/ios/WebPageIOS.mm:
     66        (WebKit::WebPage::getPositionInformation):
     67
    1682019-07-26  Zalan Bujtas  <zalan@apple.com>
    269
  • trunk/Source/WebKit/Platform/IPC/Connection.cpp

    r247822 r247868  
    2828
    2929#include "Logging.h"
     30#include "MessageFlags.h"
    3031#include <memory>
    3132#include <wtf/HashSet.h>
     
    5051#endif
    5152
     53std::atomic<unsigned> UnboundedSynchronousIPCScope::unboundedSynchronousIPCCount = 0;
     54
    5255struct Connection::ReplyHandler {
    5356    RefPtr<FunctionDispatcher> dispatcher;
     
    99102    void dispatchMessages(Connection* allowedConnection);
    100103
    101     void incrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount() { ++m_processIncomingSyncMessagesWhenWaitingForSyncReplyCount; }
    102     void decrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount() { --m_processIncomingSyncMessagesWhenWaitingForSyncReplyCount; }
    103 
    104104private:
    105105    void dispatchMessageAndResetDidScheduleDispatchMessagesForConnection(Connection&);
     
    118118    };
    119119    Vector<ConnectionAndIncomingMessage> m_messagesToDispatchWhileWaitingForSyncReply;
    120 
    121     std::atomic<unsigned> m_processIncomingSyncMessagesWhenWaitingForSyncReplyCount { 0 };
    122120};
    123121
     
    140138bool Connection::SyncMessageState::processIncomingMessage(Connection& connection, std::unique_ptr<Decoder>& message)
    141139{
    142     bool shouldDispatchMessageWhenWaitingForSyncReply = message->shouldDispatchMessageWhenWaitingForSyncReply();
    143 
    144     // We dispatch synchronous messages even if shouldDispatchMessageWhenWaitingForSyncReply returns false if the
    145     // sendSync() used SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply. This is used for some messages
    146     // in the WebContent process (which normally does not dispatch messages when waiting for a sync reply), to avoid
    147     // hangs.
    148     if (!shouldDispatchMessageWhenWaitingForSyncReply && message->isSyncMessage() && m_processIncomingSyncMessagesWhenWaitingForSyncReplyCount.load())
    149         shouldDispatchMessageWhenWaitingForSyncReply = true;
    150 
    151     if (!shouldDispatchMessageWhenWaitingForSyncReply)
     140    switch (message->shouldDispatchMessageWhenWaitingForSyncReply()) {
     141    case ShouldDispatchWhenWaitingForSyncReply::No:
    152142        return false;
     143    case ShouldDispatchWhenWaitingForSyncReply::YesDuringUnboundedIPC:
     144        if (!UnboundedSynchronousIPCScope::hasOngoingUnboundedSyncIPC())
     145            return false;
     146        break;
     147    case ShouldDispatchWhenWaitingForSyncReply::Yes:
     148        break;
     149    }
    153150
    154151    ConnectionAndIncomingMessage connectionAndIncomingMessage { connection, WTFMove(message) };
     
    434431        && (!m_onlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage
    435432            || m_inDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount))
    436         encoder->setShouldDispatchMessageWhenWaitingForSyncReply(true);
     433        encoder->setShouldDispatchMessageWhenWaitingForSyncReply(ShouldDispatchWhenWaitingForSyncReply::Yes);
     434    else if (sendOptions.contains(SendOption::DispatchMessageEvenWhenWaitingForUnboundedSyncReply))
     435        encoder->setShouldDispatchMessageWhenWaitingForSyncReply(ShouldDispatchWhenWaitingForSyncReply::YesDuringUnboundedIPC);
    437436
    438437    {
     
    578577
    579578    // First send the message.
    580     sendMessage(WTFMove(encoder), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
    581 
    582     if (sendSyncOptions.contains(SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply))
    583         SyncMessageState::singleton().incrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount();
     579    OptionSet<SendOption> sendOptions = IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply;
     580    if (sendSyncOptions.contains(SendSyncOption::ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply))
     581        sendOptions = sendOptions | IPC::SendOption::DispatchMessageEvenWhenWaitingForUnboundedSyncReply;
     582
     583    sendMessage(WTFMove(encoder), sendOptions);
    584584
    585585    // Then wait for a reply. Waiting for a reply could involve dispatching incoming sync messages, so
     
    587587    Ref<Connection> protect(*this);
    588588    std::unique_ptr<Decoder> reply = waitForSyncReply(syncRequestID, timeout, sendSyncOptions);
    589 
    590     if (sendSyncOptions.contains(SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply))
    591         SyncMessageState::singleton().decrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount();
    592589
    593590    --m_inSendSyncCount;
     
    10411038
    10421039    m_inDispatchMessageCount++;
    1043 
    1044     if (message->shouldDispatchMessageWhenWaitingForSyncReply())
     1040   
     1041    bool isDispatchingMessageWhileWaitingForSyncReply = (message->shouldDispatchMessageWhenWaitingForSyncReply() == ShouldDispatchWhenWaitingForSyncReply::Yes)
     1042        || (message->shouldDispatchMessageWhenWaitingForSyncReply() == ShouldDispatchWhenWaitingForSyncReply::YesDuringUnboundedIPC && UnboundedSynchronousIPCScope::hasOngoingUnboundedSyncIPC());
     1043
     1044    if (isDispatchingMessageWhileWaitingForSyncReply)
    10451045        m_inDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount++;
    10461046
     
    10581058    // FIXME: For synchronous messages, we should not decrement the counter until we send a response.
    10591059    // Otherwise, we would deadlock if processing the message results in a sync message back after we exit this function.
    1060     if (message->shouldDispatchMessageWhenWaitingForSyncReply())
     1060    if (isDispatchingMessageWhileWaitingForSyncReply)
    10611061        m_inDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount--;
    10621062
  • trunk/Source/WebKit/Platform/IPC/Connection.h

    r247822 r247868  
    6262    // This is the default for synchronous messages.
    6363    DispatchMessageEvenWhenWaitingForSyncReply = 1 << 0,
    64     IgnoreFullySynchronousMode = 1 << 1,
     64    DispatchMessageEvenWhenWaitingForUnboundedSyncReply = 1 << 1,
     65    IgnoreFullySynchronousMode = 1 << 2,
    6566};
    6667
     
    6970    InformPlatformProcessWillSuspend = 1 << 0,
    7071    UseFullySynchronousModeForTesting = 1 << 1,
    71     ProcessIncomingSyncMessagesWhenWaitingForSyncReply = 1 << 2,
     72    ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply = 1 << 2,
    7273};
    7374
     
    555556}
    556557
     558class UnboundedSynchronousIPCScope {
     559public:
     560    UnboundedSynchronousIPCScope()
     561    {
     562        ASSERT(RunLoop::isMain());
     563        ++unboundedSynchronousIPCCount;
     564    }
     565
     566    ~UnboundedSynchronousIPCScope()
     567    {
     568        ASSERT(RunLoop::isMain());
     569        ASSERT(unboundedSynchronousIPCCount);
     570        --unboundedSynchronousIPCCount;
     571    }
     572
     573    static bool hasOngoingUnboundedSyncIPC()
     574    {
     575        return unboundedSynchronousIPCCount.load() > 0;
     576    }
     577
     578private:
     579    static std::atomic<unsigned> unboundedSynchronousIPCCount;
     580};
     581
    557582} // namespace IPC
  • trunk/Source/WebKit/Platform/IPC/Decoder.cpp

    r239427 r247868  
    8989}
    9090
    91 bool Decoder::shouldDispatchMessageWhenWaitingForSyncReply() const
    92 {
    93     return m_messageFlags & DispatchMessageWhenWaitingForSyncReply;
     91ShouldDispatchWhenWaitingForSyncReply Decoder::shouldDispatchMessageWhenWaitingForSyncReply() const
     92{
     93    if (m_messageFlags & DispatchMessageWhenWaitingForSyncReply)
     94        return ShouldDispatchWhenWaitingForSyncReply::Yes;
     95    if (m_messageFlags & DispatchMessageWhenWaitingForUnboundedSyncReply)
     96        return ShouldDispatchWhenWaitingForSyncReply::YesDuringUnboundedIPC;
     97    return ShouldDispatchWhenWaitingForSyncReply::No;
    9498}
    9599
  • trunk/Source/WebKit/Platform/IPC/Decoder.h

    r243460 r247868  
    4040class DataReference;
    4141class ImportanceAssertion;
     42enum class ShouldDispatchWhenWaitingForSyncReply;
    4243
    4344class Decoder {
     
    5556
    5657    bool isSyncMessage() const;
    57     bool shouldDispatchMessageWhenWaitingForSyncReply() const;
     58    ShouldDispatchWhenWaitingForSyncReply shouldDispatchMessageWhenWaitingForSyncReply() const;
    5859    bool shouldUseFullySynchronousModeForTesting() const;
    5960
  • trunk/Source/WebKit/Platform/IPC/Encoder.cpp

    r238798 r247868  
    8686}
    8787
    88 bool Encoder::shouldDispatchMessageWhenWaitingForSyncReply() const
    89 {
    90     return *buffer() & DispatchMessageWhenWaitingForSyncReply;
     88ShouldDispatchWhenWaitingForSyncReply Encoder::shouldDispatchMessageWhenWaitingForSyncReply() const
     89{
     90    if (*buffer() & DispatchMessageWhenWaitingForSyncReply)
     91        return ShouldDispatchWhenWaitingForSyncReply::Yes;
     92    if (*buffer() & DispatchMessageWhenWaitingForUnboundedSyncReply)
     93        return ShouldDispatchWhenWaitingForSyncReply::YesDuringUnboundedIPC;
     94    return ShouldDispatchWhenWaitingForSyncReply::No;
    9195}
    9296
     
    99103}
    100104
    101 void Encoder::setShouldDispatchMessageWhenWaitingForSyncReply(bool shouldDispatchMessageWhenWaitingForSyncReply)
    102 {
    103     if (shouldDispatchMessageWhenWaitingForSyncReply)
     105void Encoder::setShouldDispatchMessageWhenWaitingForSyncReply(ShouldDispatchWhenWaitingForSyncReply shouldDispatchWhenWaitingForSyncReply)
     106{
     107    switch (shouldDispatchWhenWaitingForSyncReply) {
     108    case ShouldDispatchWhenWaitingForSyncReply::No:
     109        *buffer() &= ~(DispatchMessageWhenWaitingForSyncReply | DispatchMessageWhenWaitingForUnboundedSyncReply);
     110        break;
     111    case ShouldDispatchWhenWaitingForSyncReply::Yes:
    104112        *buffer() |= DispatchMessageWhenWaitingForSyncReply;
    105     else
     113        *buffer() &= ~DispatchMessageWhenWaitingForUnboundedSyncReply;
     114        break;
     115    case ShouldDispatchWhenWaitingForSyncReply::YesDuringUnboundedIPC:
     116        *buffer() |= DispatchMessageWhenWaitingForUnboundedSyncReply;
    106117        *buffer() &= ~DispatchMessageWhenWaitingForSyncReply;
     118        break;
     119    }
    107120}
    108121
     
    117130    ASSERT(!original->isSyncMessage());
    118131
    119     original->setShouldDispatchMessageWhenWaitingForSyncReply(true);
     132    original->setShouldDispatchMessageWhenWaitingForSyncReply(ShouldDispatchWhenWaitingForSyncReply::Yes);
    120133
    121134    encodeVariableLengthByteArray(DataReference(original->buffer(), original->bufferSize()));
  • trunk/Source/WebKit/Platform/IPC/Encoder.h

    r237294 r247868  
    3535
    3636class DataReference;
     37enum class ShouldDispatchWhenWaitingForSyncReply;
    3738
    3839class Encoder final {
     
    4950    bool isSyncMessage() const;
    5051
    51     void setShouldDispatchMessageWhenWaitingForSyncReply(bool);
    52     bool shouldDispatchMessageWhenWaitingForSyncReply() const;
     52    void setShouldDispatchMessageWhenWaitingForSyncReply(ShouldDispatchWhenWaitingForSyncReply);
     53    ShouldDispatchWhenWaitingForSyncReply shouldDispatchMessageWhenWaitingForSyncReply() const;
    5354
    5455    void setFullySynchronousModeForTesting();
  • trunk/Source/WebKit/Platform/IPC/MessageFlags.h

    r188793 r247868  
    3232    SyncMessage = 1 << 0,
    3333    DispatchMessageWhenWaitingForSyncReply = 1 << 1,
    34     UseFullySynchronousModeForTesting = 1 << 2,
     34    DispatchMessageWhenWaitingForUnboundedSyncReply = 1 << 2,
     35    UseFullySynchronousModeForTesting = 1 << 3,
    3536};
     37
     38enum class ShouldDispatchWhenWaitingForSyncReply { No, Yes, YesDuringUnboundedIPC };
    3639
    3740} // namespace IPC
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp

    r247822 r247868  
    12121212
    12131213    bool handled = false;
    1214     if (!page->sendSync(Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply(), Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::Reply(handled)))
     1214    if (!page->sendSync(Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply(), Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::Reply(handled), Seconds::infinity(), IPC::SendSyncOption::ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply))
    12151215        return reply(false);
    12161216    reply(handled);
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r247866 r247868  
    26702670    m_process->responsivenessTimer().start();
    26712671    bool handled = false;
    2672     bool replyReceived = m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID, 1_s);
     2672    bool replyReceived = m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID, 1_s, IPC::SendSyncOption::ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply);
    26732673    // If the sync request has timed out, we should consider the event handled. The Web Process is too busy to answer any questions, so the default action is also likely to have issues.
    26742674    if (!replyReceived)
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r247866 r247868  
    20002000        return connection->waitForAndDispatchImmediately<Messages::WebPageProxy::DidReceivePositionInformation>(_page->pageID(), 1_s, IPC::WaitForOption::InterruptWaitingIfSyncMessageArrives);
    20012001
    2002     bool receivedResponse = _page->process().sendSync(Messages::WebPage::GetPositionInformation(request), Messages::WebPage::GetPositionInformation::Reply(_positionInformation), _page->pageID(), 1_s);
     2002    bool receivedResponse = _page->process().sendSync(Messages::WebPage::GetPositionInformation(request), Messages::WebPage::GetPositionInformation::Reply(_positionInformation), _page->pageID(), 1_s, IPC::SendSyncOption::ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply);
    20032003    _hasValidPositionInformation = receivedResponse && _positionInformation.canBeValid;
    20042004   
  • trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp

    r246452 r247868  
    565565
    566566    HangDetectionDisabler hangDetectionDisabler;
     567    IPC::UnboundedSynchronousIPCScope unboundedSynchronousIPCScope;
    567568
    568569    bool shouldNotifyOfUpload = request.hasUpload() && m_loadersWithUploads.isEmpty();
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp

    r247822 r247868  
    308308bool WebChromeClient::testProcessIncomingSyncMessagesWhenWaitingForSyncReply()
    309309{
     310    IPC::UnboundedSynchronousIPCScope unboundedSynchronousIPCScope;
    310311    bool handled = false;
    311     if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply(m_page.pageID()), Messages::NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::Reply(handled), 0, Seconds::infinity(), IPC::SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply))
     312    if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply(m_page.pageID()), Messages::NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::Reply(handled), 0))
    312313        return false;
    313314    return handled;
     
    468469
    469470    HangDetectionDisabler hangDetectionDisabler;
    470 
    471     m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptAlert(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), alertText), Messages::WebPageProxy::RunJavaScriptAlert::Reply(), IPC::SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply);
     471    IPC::UnboundedSynchronousIPCScope unboundedSynchronousIPCScope;
     472
     473    m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptAlert(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), alertText), Messages::WebPageProxy::RunJavaScriptAlert::Reply());
    472474}
    473475
     
    484486
    485487    HangDetectionDisabler hangDetectionDisabler;
     488    IPC::UnboundedSynchronousIPCScope unboundedSynchronousIPCScope;
    486489
    487490    bool result = false;
    488     if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptConfirm(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message), Messages::WebPageProxy::RunJavaScriptConfirm::Reply(result), IPC::SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply))
     491    if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptConfirm(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message), Messages::WebPageProxy::RunJavaScriptConfirm::Reply(result)))
    489492        return false;
    490493
     
    504507
    505508    HangDetectionDisabler hangDetectionDisabler;
    506 
    507     if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptPrompt(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message, defaultValue), Messages::WebPageProxy::RunJavaScriptPrompt::Reply(result), IPC::SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply))
     509    IPC::UnboundedSynchronousIPCScope unboundedSynchronousIPCScope;
     510
     511    if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptPrompt(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message, defaultValue), Messages::WebPageProxy::RunJavaScriptPrompt::Reply(result)))
    508512        return false;
    509513
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r247866 r247868  
    317317static const Seconds maximumLayerVolatilityTimerInterval { 2_s };
    318318
    319 #define RELEASE_LOG_IF_ALLOWED(...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), Layers, __VA_ARGS__)
    320 #define RELEASE_LOG_ERROR_IF_ALLOWED(...) RELEASE_LOG_ERROR_IF(isAlwaysOnLoggingAllowed(), Layers, __VA_ARGS__)
     319#define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - WebPage::" fmt, this, ##__VA_ARGS__)
     320#define RELEASE_LOG_ERROR_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_ERROR_IF(isAlwaysOnLoggingAllowed(), channel, "%p - WebPage::" fmt, this, ##__VA_ARGS__)
    321321
    322322class SendStopResponsivenessTimer {
     
    25572557        m_layerVolatilityTimer.stop();
    25582558        if (didSucceed)
    2559             RELEASE_LOG_IF_ALLOWED("%p - WebPage - Succeeded in marking layers as volatile", this);
     2559            RELEASE_LOG_IF_ALLOWED(Layers, "layerVolatilityTimerFired: Succeeded in marking layers as volatile");
    25602560        else
    2561             RELEASE_LOG_IF_ALLOWED("%p - WebPage - Failed to mark layers as volatile within %gms", this, maximumLayerVolatilityTimerInterval.milliseconds());
     2561            RELEASE_LOG_IF_ALLOWED(Layers, "layerVolatilityTimerFired: Failed to mark layers as volatile within %gms", maximumLayerVolatilityTimerInterval.milliseconds());
    25622562        callVolatilityCompletionHandlers(didSucceed);
    25632563        return;
    25642564    }
    25652565
    2566     RELEASE_LOG_ERROR_IF_ALLOWED("%p - WebPage - Failed to mark all layers as volatile, will retry in %g ms", this, newInterval.milliseconds());
     2566    RELEASE_LOG_ERROR_IF_ALLOWED(Layers, "layerVolatilityTimerFired: Failed to mark all layers as volatile, will retry in %g ms", newInterval.milliseconds());
    25672567    m_layerVolatilityTimer.startRepeating(newInterval);
    25682568}
     
    25752575void WebPage::markLayersVolatile(WTF::Function<void (bool)>&& completionHandler)
    25762576{
    2577     RELEASE_LOG_IF_ALLOWED("%p - WebPage::markLayersVolatile()", this);
     2577    RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile");
    25782578
    25792579    if (m_layerVolatilityTimer.isActive())
     
    25862586    if (didSucceed || m_isSuspendedUnderLock) {
    25872587        if (didSucceed)
    2588             RELEASE_LOG_IF_ALLOWED("%p - WebPage - Successfully marked layers as volatile", this);
     2588            RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile: Successfully marked layers as volatile");
    25892589        else {
    25902590            // If we get suspended when locking the screen, it is expected that some IOSurfaces cannot be marked as purgeable so we do not keep retrying.
    2591             RELEASE_LOG_IF_ALLOWED("%p - WebPage - Did what we could to mark IOSurfaces as purgeable after locking the screen", this);
     2591            RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile: Did what we could to mark IOSurfaces as purgeable after locking the screen");
    25922592        }
    25932593        callVolatilityCompletionHandlers(didSucceed);
     
    25952595    }
    25962596
    2597     RELEASE_LOG_IF_ALLOWED("%p - Failed to mark all layers as volatile, will retry in %g ms", this, initialLayerVolatilityTimerInterval.milliseconds());
     2597    RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile: Failed to mark all layers as volatile, will retry in %g ms", initialLayerVolatilityTimerInterval.milliseconds());
    25982598    m_layerVolatilityTimer.startRepeating(initialLayerVolatilityTimerInterval);
    25992599}
     
    26012601void WebPage::cancelMarkLayersVolatile()
    26022602{
    2603     RELEASE_LOG_IF_ALLOWED("%p - WebPage::cancelMarkLayersVolatile()", this);
     2603    RELEASE_LOG_IF_ALLOWED(Layers, "cancelMarkLayersVolatile");
    26042604    m_layerVolatilityTimer.stop();
    26052605    m_markLayersAsVolatileCompletionHandlers.clear();
     
    29112911void WebPage::touchEventSync(const WebTouchEvent& touchEvent, CompletionHandler<void(bool)>&& reply)
    29122912{
     2913    // Avoid UIProcess hangs when the WebContent process is stuck on a sync IPC.
     2914    if (IPC::UnboundedSynchronousIPCScope::hasOngoingUnboundedSyncIPC()) {
     2915        RELEASE_LOG_ERROR_IF_ALLOWED(Process, "touchEventSync - Not processing because the process is stuck on unbounded sync IPC");
     2916        return reply(true);
     2917    }
     2918
    29132919    m_pendingSynchronousTouchEventReply = WTFMove(reply);
    29142920
     
    32803286    unfreezeLayerTree(LayerTreeFreezeReason::PageTransition);
    32813287
    3282     RELEASE_LOG_IF_ALLOWED("%p - WebPage - Did complete page transition", this);
     3288    RELEASE_LOG_IF_ALLOWED(Layers, "didCompletePageTransition: Did complete page transition");
    32833289
    32843290    bool isInitialEmptyDocument = !m_mainFrame;
     
    35453551#if !PLATFORM(GTK) && !PLATFORM(WIN)
    35463552    if (!settings.acceleratedCompositingEnabled()) {
    3547         RELEASE_LOG_IF_ALLOWED("%p - WebPage - acceleratedCompositingEnabled setting was false. WebKit cannot function in this mode; changing setting to true", this);
     3553        RELEASE_LOG_IF_ALLOWED(Layers, "updatePreferences: acceleratedCompositingEnabled setting was false. WebKit cannot function in this mode; changing setting to true");
    35483554        settings.setAcceleratedCompositingEnabled(true);
    35493555    }
     
    58865892void WebPage::testProcessIncomingSyncMessagesWhenWaitingForSyncReply(Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::DelayedReply&& reply)
    58875893{
     5894    RELEASE_ASSERT(IPC::UnboundedSynchronousIPCScope::hasOngoingUnboundedSyncIPC());
    58885895    reply(true);
    58895896}
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r247866 r247868  
    11681168
    11691169    template<typename T>
    1170     bool sendSyncWithDelayedReply(T&& message, typename T::Reply&& reply, OptionSet<IPC::SendSyncOption> sendSyncOptions = { })
     1170    bool sendSyncWithDelayedReply(T&& message, typename T::Reply&& reply)
    11711171    {
    11721172        cancelGesturesBlockedOnSynchronousReplies();
    1173         return sendSync(WTFMove(message), WTFMove(reply), Seconds::infinity(), sendSyncOptions | IPC::SendSyncOption::InformPlatformProcessWillSuspend);
     1173        return sendSync(WTFMove(message), WTFMove(reply), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend);
    11741174    }
    11751175
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r247866 r247868  
    133133#import <wtf/text/TextStream.h>
    134134
     135#define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - WebPage::" fmt, this, ##__VA_ARGS__)
     136#define RELEASE_LOG_ERROR_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_ERROR_IF(isAlwaysOnLoggingAllowed(), channel, "%p - WebPage::" fmt, this, ##__VA_ARGS__)
     137
    135138namespace WebKit {
    136139using namespace WebCore;
     
    25172520void WebPage::getPositionInformation(const InteractionInformationRequest& request, CompletionHandler<void(InteractionInformationAtPosition&&)>&& reply)
    25182521{
     2522    // Avoid UIProcess hangs when the WebContent process is stuck on a sync IPC.
     2523    if (IPC::UnboundedSynchronousIPCScope::hasOngoingUnboundedSyncIPC()) {
     2524        RELEASE_LOG_ERROR_IF_ALLOWED(Process, "getPositionInformation - Not processing because the process is stuck on unbounded sync IPC");
     2525        return reply({ });
     2526    }
     2527
    25192528    m_pendingSynchronousPositionInformationReply = WTFMove(reply);
    25202529
     
    40164025} // namespace WebKit
    40174026
     4027#undef RELEASE_LOG_IF_ALLOWED
     4028#undef RELEASE_LOG_ERROR_IF_ALLOWED
     4029
    40184030#endif // PLATFORM(IOS_FAMILY)
Note: See TracChangeset for help on using the changeset viewer.