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

Changeset 248349 in webkit


Ignore:
Timestamp:
Aug 6, 2019, 11:52:34 PM (7 years ago)
Author:
Kocsen Chung
Message:

Cherry-pick r247822. rdar://problem/54017886

Avoid UI Process hangs when the WebContent process is showing JS prompts / alerts
https://bugs.webkit.org/show_bug.cgi?id=200107
<rdar://problem/53034592>

Reviewed by Geoffrey Garen.

Source/WebCore:

Add testing infrastructure for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply.

Test: fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html

  • page/ChromeClient.h:
  • testing/Internals.cpp: (WebCore::Internals::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
  • testing/Internals.h:
  • testing/Internals.idl:

Source/WebKit:

  • Platform/IPC/Connection.cpp: (IPC::Connection::SyncMessageState::incrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount): (IPC::Connection::SyncMessageState::decrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount): (IPC::Connection::SyncMessageState::processIncomingMessage): (IPC::Connection::sendSyncMessage):
  • Platform/IPC/Connection.h: Add support for new SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag to allow processing incoming sync messages while sending a particular sync IPC. This is the default behavior in all processes except in the WebContent process, where we try to avoid re-entering to prevent bugs. This flag allows the WebContent process to change its default behavior for some specific IPCs, where we know it is safe to re-enter and where it benefits performance to re-renter.
  • NetworkProcess/NetworkConnectionToWebProcess.cpp: (WebKit::NetworkConnectionToWebProcess::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
  • NetworkProcess/NetworkConnectionToWebProcess.h:
  • NetworkProcess/NetworkConnectionToWebProcess.messages.in:
  • UIProcess/Network/NetworkProcessProxy.cpp: (WebKit::NetworkProcessProxy::didReceiveSyncMessage): (WebKit::NetworkProcessProxy::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
  • UIProcess/Network/NetworkProcessProxy.h:
  • UIProcess/Network/NetworkProcessProxy.messages.in:
  • WebProcess/WebCoreSupport/WebChromeClient.cpp: (WebKit::WebChromeClient::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
  • WebProcess/WebCoreSupport/WebChromeClient.h:
  • WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
  • WebProcess/WebPage/WebPage.h: (WebKit::WebPage::sendSyncWithDelayedReply):
  • WebProcess/WebPage/WebPage.messages.in: SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply Add testing infrastructure for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag.
  • WebProcess/WebCoreSupport/WebChromeClient.cpp: (WebKit::WebChromeClient::runJavaScriptAlert): (WebKit::WebChromeClient::runJavaScriptConfirm): (WebKit::WebChromeClient::runJavaScriptPrompt): Use new SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag when sending the synchronous IPC for JS alerts / prompt / confirm. This allows the WebProcess to process incoming synchronous IPC for other processes (in particular the UIProcess) while it is blocked on those synchronous IPCs. It is safe to re-enter the WebContent process on these sync IPCs since they are triggered by JS and we return to JS right after. This should avoid UIProcess hangs when the UIProcess is sending a sync IPC to the WebContent process, which is itself stuck on the sync IPC to show a JS alert.

LayoutTests:

Add layout test coverage for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply.
Without the flag on the sendSync from the WebContent process of the
NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply IPC, the
test would hang. This is because the WebContent process sends a sync IPC to the network process,
which in turns sends one to the UIProcess, which itself sends one back to the WebContent process.
This would attempt to re-enter the WebContent process which is currently sending a sync IPC, which
is not allowed by default.

  • fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply-expected.txt: Added.
  • fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247822 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Location:
branches/safari-608.1-branch
Files:
2 added
20 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-608.1-branch/LayoutTests/ChangeLog

    r248347 r248349  
     12019-08-06  Kocsen Chung  <kocsen_chung@apple.com>
     2
     3        Cherry-pick r247822. rdar://problem/54017886
     4
     5    Avoid UI Process hangs when the WebContent process is showing JS prompts / alerts
     6    https://bugs.webkit.org/show_bug.cgi?id=200107
     7    <rdar://problem/53034592>
     8   
     9    Reviewed by Geoffrey Garen.
     10   
     11    Source/WebCore:
     12   
     13    Add testing infrastructure for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply.
     14   
     15    Test: fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html
     16   
     17    * page/ChromeClient.h:
     18    * testing/Internals.cpp:
     19    (WebCore::Internals::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     20    * testing/Internals.h:
     21    * testing/Internals.idl:
     22   
     23    Source/WebKit:
     24   
     25    * Platform/IPC/Connection.cpp:
     26    (IPC::Connection::SyncMessageState::incrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount):
     27    (IPC::Connection::SyncMessageState::decrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount):
     28    (IPC::Connection::SyncMessageState::processIncomingMessage):
     29    (IPC::Connection::sendSyncMessage):
     30    * Platform/IPC/Connection.h:
     31    Add support for new SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag
     32    to allow processing incoming sync messages while sending a particular sync IPC. This is the
     33    default behavior in all processes except in the WebContent process, where we try to avoid
     34    re-entering to prevent bugs. This flag allows the WebContent process to change its default
     35    behavior for some specific IPCs, where we know it is safe to re-enter and where it benefits
     36    performance to re-renter.
     37   
     38    * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     39    (WebKit::NetworkConnectionToWebProcess::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     40    * NetworkProcess/NetworkConnectionToWebProcess.h:
     41    * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
     42    * UIProcess/Network/NetworkProcessProxy.cpp:
     43    (WebKit::NetworkProcessProxy::didReceiveSyncMessage):
     44    (WebKit::NetworkProcessProxy::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     45    * UIProcess/Network/NetworkProcessProxy.h:
     46    * UIProcess/Network/NetworkProcessProxy.messages.in:
     47    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     48    (WebKit::WebChromeClient::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     49    * WebProcess/WebCoreSupport/WebChromeClient.h:
     50    * WebProcess/WebPage/WebPage.cpp:
     51    (WebKit::WebPage::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     52    * WebProcess/WebPage/WebPage.h:
     53    (WebKit::WebPage::sendSyncWithDelayedReply):
     54    * WebProcess/WebPage/WebPage.messages.in:
     55    SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply
     56    Add testing infrastructure for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply
     57    flag.
     58   
     59    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     60    (WebKit::WebChromeClient::runJavaScriptAlert):
     61    (WebKit::WebChromeClient::runJavaScriptConfirm):
     62    (WebKit::WebChromeClient::runJavaScriptPrompt):
     63    Use new SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag when sending
     64    the synchronous IPC for JS alerts / prompt / confirm. This allows the WebProcess to process
     65    incoming synchronous IPC for other processes (in particular the UIProcess) while it is blocked
     66    on those synchronous IPCs. It is safe to re-enter the WebContent process on these sync IPCs
     67    since they are triggered by JS and we return to JS right after. This should avoid UIProcess
     68    hangs when the UIProcess is sending a sync IPC to the WebContent process, which is itself
     69    stuck on the sync IPC to show a JS alert.
     70   
     71    LayoutTests:
     72   
     73    Add layout test coverage for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply.
     74    Without the flag on the sendSync from the WebContent process of the
     75    NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply IPC, the
     76    test would hang. This is because the WebContent process sends a sync IPC to the network process,
     77    which in turns sends one to the UIProcess, which itself sends one back to the WebContent process.
     78    This would attempt to re-enter the WebContent process which is currently sending a sync IPC, which
     79    is not allowed by default.
     80   
     81    * fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply-expected.txt: Added.
     82    * fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html: Added.
     83   
     84    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247822 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     85
     86    2019-07-25  Chris Dumez  <cdumez@apple.com>
     87
     88            Avoid UI Process hangs when the WebContent process is showing JS prompts / alerts
     89            https://bugs.webkit.org/show_bug.cgi?id=200107
     90            <rdar://problem/53034592>
     91
     92            Reviewed by Geoffrey Garen.
     93
     94            Add layout test coverage for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply.
     95            Without the flag on the sendSync from the WebContent process of the
     96            NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply IPC, the
     97            test would hang. This is because the WebContent process sends a sync IPC to the network process,
     98            which in turns sends one to the UIProcess, which itself sends one back to the WebContent process.
     99            This would attempt to re-enter the WebContent process which is currently sending a sync IPC, which
     100            is not allowed by default.
     101
     102            * fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply-expected.txt: Added.
     103            * fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html: Added.
     104
    11052019-08-06  Kocsen Chung  <kocsen_chung@apple.com>
    2106
  • branches/safari-608.1-branch/Source/WebCore/ChangeLog

    r248347 r248349  
     12019-08-06  Kocsen Chung  <kocsen_chung@apple.com>
     2
     3        Cherry-pick r247822. rdar://problem/54017886
     4
     5    Avoid UI Process hangs when the WebContent process is showing JS prompts / alerts
     6    https://bugs.webkit.org/show_bug.cgi?id=200107
     7    <rdar://problem/53034592>
     8   
     9    Reviewed by Geoffrey Garen.
     10   
     11    Source/WebCore:
     12   
     13    Add testing infrastructure for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply.
     14   
     15    Test: fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html
     16   
     17    * page/ChromeClient.h:
     18    * testing/Internals.cpp:
     19    (WebCore::Internals::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     20    * testing/Internals.h:
     21    * testing/Internals.idl:
     22   
     23    Source/WebKit:
     24   
     25    * Platform/IPC/Connection.cpp:
     26    (IPC::Connection::SyncMessageState::incrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount):
     27    (IPC::Connection::SyncMessageState::decrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount):
     28    (IPC::Connection::SyncMessageState::processIncomingMessage):
     29    (IPC::Connection::sendSyncMessage):
     30    * Platform/IPC/Connection.h:
     31    Add support for new SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag
     32    to allow processing incoming sync messages while sending a particular sync IPC. This is the
     33    default behavior in all processes except in the WebContent process, where we try to avoid
     34    re-entering to prevent bugs. This flag allows the WebContent process to change its default
     35    behavior for some specific IPCs, where we know it is safe to re-enter and where it benefits
     36    performance to re-renter.
     37   
     38    * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     39    (WebKit::NetworkConnectionToWebProcess::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     40    * NetworkProcess/NetworkConnectionToWebProcess.h:
     41    * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
     42    * UIProcess/Network/NetworkProcessProxy.cpp:
     43    (WebKit::NetworkProcessProxy::didReceiveSyncMessage):
     44    (WebKit::NetworkProcessProxy::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     45    * UIProcess/Network/NetworkProcessProxy.h:
     46    * UIProcess/Network/NetworkProcessProxy.messages.in:
     47    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     48    (WebKit::WebChromeClient::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     49    * WebProcess/WebCoreSupport/WebChromeClient.h:
     50    * WebProcess/WebPage/WebPage.cpp:
     51    (WebKit::WebPage::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     52    * WebProcess/WebPage/WebPage.h:
     53    (WebKit::WebPage::sendSyncWithDelayedReply):
     54    * WebProcess/WebPage/WebPage.messages.in:
     55    SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply
     56    Add testing infrastructure for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply
     57    flag.
     58   
     59    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     60    (WebKit::WebChromeClient::runJavaScriptAlert):
     61    (WebKit::WebChromeClient::runJavaScriptConfirm):
     62    (WebKit::WebChromeClient::runJavaScriptPrompt):
     63    Use new SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag when sending
     64    the synchronous IPC for JS alerts / prompt / confirm. This allows the WebProcess to process
     65    incoming synchronous IPC for other processes (in particular the UIProcess) while it is blocked
     66    on those synchronous IPCs. It is safe to re-enter the WebContent process on these sync IPCs
     67    since they are triggered by JS and we return to JS right after. This should avoid UIProcess
     68    hangs when the UIProcess is sending a sync IPC to the WebContent process, which is itself
     69    stuck on the sync IPC to show a JS alert.
     70   
     71    LayoutTests:
     72   
     73    Add layout test coverage for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply.
     74    Without the flag on the sendSync from the WebContent process of the
     75    NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply IPC, the
     76    test would hang. This is because the WebContent process sends a sync IPC to the network process,
     77    which in turns sends one to the UIProcess, which itself sends one back to the WebContent process.
     78    This would attempt to re-enter the WebContent process which is currently sending a sync IPC, which
     79    is not allowed by default.
     80   
     81    * fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply-expected.txt: Added.
     82    * fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html: Added.
     83   
     84    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247822 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     85
     86    2019-07-25  Chris Dumez  <cdumez@apple.com>
     87
     88            Avoid UI Process hangs when the WebContent process is showing JS prompts / alerts
     89            https://bugs.webkit.org/show_bug.cgi?id=200107
     90            <rdar://problem/53034592>
     91
     92            Reviewed by Geoffrey Garen.
     93
     94            Add testing infrastructure for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply.
     95
     96            Test: fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html
     97
     98            * page/ChromeClient.h:
     99            * testing/Internals.cpp:
     100            (WebCore::Internals::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     101            * testing/Internals.h:
     102            * testing/Internals.idl:
     103
    11042019-08-06  Kocsen Chung  <kocsen_chung@apple.com>
    2105
  • branches/safari-608.1-branch/Source/WebCore/page/ChromeClient.h

    r246285 r248349  
    382382#endif
    383383
     384    virtual bool testProcessIncomingSyncMessagesWhenWaitingForSyncReply() { return true; }
     385
    384386#if PLATFORM(IOS_FAMILY)
    385387    // FIXME: Come up with a more descriptive name for this function and make it platform independent (if possible).
  • branches/safari-608.1-branch/Source/WebCore/testing/Internals.cpp

    r248347 r248349  
    22652265}
    22662266
     2267bool Internals::testProcessIncomingSyncMessagesWhenWaitingForSyncReply()
     2268{
     2269    ASSERT(contextDocument());
     2270    ASSERT(contextDocument()->page());
     2271    return contextDocument()->page()->chrome().client().testProcessIncomingSyncMessagesWhenWaitingForSyncReply();
     2272}
     2273
    22672274void Internals::setAutomaticDashSubstitutionEnabled(bool enabled)
    22682275{
  • branches/safari-608.1-branch/Source/WebCore/testing/Internals.h

    r248347 r248349  
    331331    void toggleOverwriteModeEnabled();
    332332
     333    bool testProcessIncomingSyncMessagesWhenWaitingForSyncReply();
     334
    333335    ExceptionOr<RefPtr<Range>> rangeOfString(const String&, RefPtr<Range>&&, const Vector<String>& findOptions);
    334336    ExceptionOr<unsigned> countMatchesForText(const String&, const Vector<String>& findOptions, const String& markMatches);
  • branches/safari-608.1-branch/Source/WebCore/testing/Internals.idl

    r248347 r248349  
    383383    [MayThrowException] double svgAnimationsInterval(SVGSVGElement element);
    384384
     385    boolean testProcessIncomingSyncMessagesWhenWaitingForSyncReply();
     386
    385387    // Flags for layerTreeAsText.
    386388    const unsigned short LAYER_TREE_INCLUDES_VISIBLE_RECTS = 1;
  • branches/safari-608.1-branch/Source/WebKit/ChangeLog

    r248348 r248349  
     12019-08-06  Kocsen Chung  <kocsen_chung@apple.com>
     2
     3        Cherry-pick r247822. rdar://problem/54017886
     4
     5    Avoid UI Process hangs when the WebContent process is showing JS prompts / alerts
     6    https://bugs.webkit.org/show_bug.cgi?id=200107
     7    <rdar://problem/53034592>
     8   
     9    Reviewed by Geoffrey Garen.
     10   
     11    Source/WebCore:
     12   
     13    Add testing infrastructure for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply.
     14   
     15    Test: fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html
     16   
     17    * page/ChromeClient.h:
     18    * testing/Internals.cpp:
     19    (WebCore::Internals::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     20    * testing/Internals.h:
     21    * testing/Internals.idl:
     22   
     23    Source/WebKit:
     24   
     25    * Platform/IPC/Connection.cpp:
     26    (IPC::Connection::SyncMessageState::incrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount):
     27    (IPC::Connection::SyncMessageState::decrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount):
     28    (IPC::Connection::SyncMessageState::processIncomingMessage):
     29    (IPC::Connection::sendSyncMessage):
     30    * Platform/IPC/Connection.h:
     31    Add support for new SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag
     32    to allow processing incoming sync messages while sending a particular sync IPC. This is the
     33    default behavior in all processes except in the WebContent process, where we try to avoid
     34    re-entering to prevent bugs. This flag allows the WebContent process to change its default
     35    behavior for some specific IPCs, where we know it is safe to re-enter and where it benefits
     36    performance to re-renter.
     37   
     38    * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     39    (WebKit::NetworkConnectionToWebProcess::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     40    * NetworkProcess/NetworkConnectionToWebProcess.h:
     41    * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
     42    * UIProcess/Network/NetworkProcessProxy.cpp:
     43    (WebKit::NetworkProcessProxy::didReceiveSyncMessage):
     44    (WebKit::NetworkProcessProxy::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     45    * UIProcess/Network/NetworkProcessProxy.h:
     46    * UIProcess/Network/NetworkProcessProxy.messages.in:
     47    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     48    (WebKit::WebChromeClient::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     49    * WebProcess/WebCoreSupport/WebChromeClient.h:
     50    * WebProcess/WebPage/WebPage.cpp:
     51    (WebKit::WebPage::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     52    * WebProcess/WebPage/WebPage.h:
     53    (WebKit::WebPage::sendSyncWithDelayedReply):
     54    * WebProcess/WebPage/WebPage.messages.in:
     55    SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply
     56    Add testing infrastructure for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply
     57    flag.
     58   
     59    * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     60    (WebKit::WebChromeClient::runJavaScriptAlert):
     61    (WebKit::WebChromeClient::runJavaScriptConfirm):
     62    (WebKit::WebChromeClient::runJavaScriptPrompt):
     63    Use new SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag when sending
     64    the synchronous IPC for JS alerts / prompt / confirm. This allows the WebProcess to process
     65    incoming synchronous IPC for other processes (in particular the UIProcess) while it is blocked
     66    on those synchronous IPCs. It is safe to re-enter the WebContent process on these sync IPCs
     67    since they are triggered by JS and we return to JS right after. This should avoid UIProcess
     68    hangs when the UIProcess is sending a sync IPC to the WebContent process, which is itself
     69    stuck on the sync IPC to show a JS alert.
     70   
     71    LayoutTests:
     72   
     73    Add layout test coverage for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply.
     74    Without the flag on the sendSync from the WebContent process of the
     75    NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply IPC, the
     76    test would hang. This is because the WebContent process sends a sync IPC to the network process,
     77    which in turns sends one to the UIProcess, which itself sends one back to the WebContent process.
     78    This would attempt to re-enter the WebContent process which is currently sending a sync IPC, which
     79    is not allowed by default.
     80   
     81    * fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply-expected.txt: Added.
     82    * fast/misc/testProcessIncomingSyncMessagesWhenWaitingForSyncReply.html: Added.
     83   
     84    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247822 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     85
     86    2019-07-25  Chris Dumez  <cdumez@apple.com>
     87
     88            Avoid UI Process hangs when the WebContent process is showing JS prompts / alerts
     89            https://bugs.webkit.org/show_bug.cgi?id=200107
     90            <rdar://problem/53034592>
     91
     92            Reviewed by Geoffrey Garen.
     93
     94            * Platform/IPC/Connection.cpp:
     95            (IPC::Connection::SyncMessageState::incrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount):
     96            (IPC::Connection::SyncMessageState::decrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount):
     97            (IPC::Connection::SyncMessageState::processIncomingMessage):
     98            (IPC::Connection::sendSyncMessage):
     99            * Platform/IPC/Connection.h:
     100            Add support for new SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag
     101            to allow processing incoming sync messages while sending a particular sync IPC. This is the
     102            default behavior in all processes except in the WebContent process, where we try to avoid
     103            re-entering to prevent bugs. This flag allows the WebContent process to change its default
     104            behavior for some specific IPCs, where we know it is safe to re-enter and where it benefits
     105            performance to re-renter.
     106
     107            * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     108            (WebKit::NetworkConnectionToWebProcess::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     109            * NetworkProcess/NetworkConnectionToWebProcess.h:
     110            * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
     111            * UIProcess/Network/NetworkProcessProxy.cpp:
     112            (WebKit::NetworkProcessProxy::didReceiveSyncMessage):
     113            (WebKit::NetworkProcessProxy::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     114            * UIProcess/Network/NetworkProcessProxy.h:
     115            * UIProcess/Network/NetworkProcessProxy.messages.in:
     116            * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     117            (WebKit::WebChromeClient::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     118            * WebProcess/WebCoreSupport/WebChromeClient.h:
     119            * WebProcess/WebPage/WebPage.cpp:
     120            (WebKit::WebPage::testProcessIncomingSyncMessagesWhenWaitingForSyncReply):
     121            * WebProcess/WebPage/WebPage.h:
     122            (WebKit::WebPage::sendSyncWithDelayedReply):
     123            * WebProcess/WebPage/WebPage.messages.in:
     124            SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply
     125            Add testing infrastructure for SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply
     126            flag.
     127
     128            * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     129            (WebKit::WebChromeClient::runJavaScriptAlert):
     130            (WebKit::WebChromeClient::runJavaScriptConfirm):
     131            (WebKit::WebChromeClient::runJavaScriptPrompt):
     132            Use new SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply flag when sending
     133            the synchronous IPC for JS alerts / prompt / confirm. This allows the WebProcess to process
     134            incoming synchronous IPC for other processes (in particular the UIProcess) while it is blocked
     135            on those synchronous IPCs. It is safe to re-enter the WebContent process on these sync IPCs
     136            since they are triggered by JS and we return to JS right after. This should avoid UIProcess
     137            hangs when the UIProcess is sending a sync IPC to the WebContent process, which is itself
     138            stuck on the sync IPC to show a JS alert.
     139
    11402019-08-06  Kocsen Chung  <kocsen_chung@apple.com>
    2141
  • branches/safari-608.1-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp

    r248108 r248349  
    3535#include "NetworkProcessConnectionMessages.h"
    3636#include "NetworkProcessMessages.h"
     37#include "NetworkProcessProxyMessages.h"
    3738#include "NetworkRTCMonitorMessages.h"
    3839#include "NetworkRTCProviderMessages.h"
     
    410411}
    411412
     413void NetworkConnectionToWebProcess::testProcessIncomingSyncMessagesWhenWaitingForSyncReply(WebCore::PageIdentifier webPageID, Messages::NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::DelayedReply&& reply)
     414{
     415    bool handled = false;
     416    if (!m_networkProcess->parentProcessConnection()->sendSync(Messages::NetworkProcessProxy::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply(webPageID), Messages::NetworkProcessProxy::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::Reply(handled), 0))
     417        return reply(false);
     418    reply(handled);
     419}
     420
    412421void NetworkConnectionToWebProcess::loadPing(NetworkResourceLoadParameters&& loadParameters)
    413422{
  • branches/safari-608.1-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h

    r246452 r248349  
    166166    void scheduleResourceLoad(NetworkResourceLoadParameters&&);
    167167    void performSynchronousLoad(NetworkResourceLoadParameters&&, Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply&&);
     168    void testProcessIncomingSyncMessagesWhenWaitingForSyncReply(WebCore::PageIdentifier, Messages::NetworkConnectionToWebProcess::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::DelayedReply&&);
    168169    void loadPing(NetworkResourceLoadParameters&&);
    169170    void prefetchDNS(const String&);
  • branches/safari-608.1-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in

    r246452 r248349  
    2525    ScheduleResourceLoad(WebKit::NetworkResourceLoadParameters resourceLoadParameters)
    2626    PerformSynchronousLoad(WebKit::NetworkResourceLoadParameters resourceLoadParameters) -> (WebCore::ResourceError error, WebCore::ResourceResponse response, Vector<char> data) Synchronous
     27    TestProcessIncomingSyncMessagesWhenWaitingForSyncReply(WebCore::PageIdentifier webPageID) -> (bool handled) Synchronous
    2728    LoadPing(WebKit::NetworkResourceLoadParameters resourceLoadParameters)
    2829    RemoveLoadIdentifier(uint64_t resourceLoadIdentifier)
  • branches/safari-608.1-branch/Source/WebKit/Platform/IPC/Connection.cpp

    r247594 r248349  
    9999    void dispatchMessages(Connection* allowedConnection);
    100100
     101    void incrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount() { ++m_processIncomingSyncMessagesWhenWaitingForSyncReplyCount; }
     102    void decrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount() { --m_processIncomingSyncMessagesWhenWaitingForSyncReplyCount; }
     103
    101104private:
    102105    void dispatchMessageAndResetDidScheduleDispatchMessagesForConnection(Connection&);
     
    115118    };
    116119    Vector<ConnectionAndIncomingMessage> m_messagesToDispatchWhileWaitingForSyncReply;
     120
     121    std::atomic<unsigned> m_processIncomingSyncMessagesWhenWaitingForSyncReplyCount { 0 };
    117122};
    118123
     
    135140bool Connection::SyncMessageState::processIncomingMessage(Connection& connection, std::unique_ptr<Decoder>& message)
    136141{
    137     if (!message->shouldDispatchMessageWhenWaitingForSyncReply())
     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)
    138152        return false;
    139153
     
    566580    sendMessage(WTFMove(encoder), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
    567581
     582    if (sendSyncOptions.contains(SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply))
     583        SyncMessageState::singleton().incrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount();
     584
    568585    // Then wait for a reply. Waiting for a reply could involve dispatching incoming sync messages, so
    569586    // keep an extra reference to the connection here in case it's invalidated.
    570587    Ref<Connection> protect(*this);
    571588    std::unique_ptr<Decoder> reply = waitForSyncReply(syncRequestID, timeout, sendSyncOptions);
     589
     590    if (sendSyncOptions.contains(SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply))
     591        SyncMessageState::singleton().decrementProcessIncomingSyncMessagesWhenWaitingForSyncReplyCount();
    572592
    573593    --m_inSendSyncCount;
  • branches/safari-608.1-branch/Source/WebKit/Platform/IPC/Connection.h

    r247594 r248349  
    6969    InformPlatformProcessWillSuspend = 1 << 0,
    7070    UseFullySynchronousModeForTesting = 1 << 1,
     71    ProcessIncomingSyncMessagesWhenWaitingForSyncReply = 1 << 2,
    7172};
    7273
  • branches/safari-608.1-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp

    r245796 r248349  
    4141#include "StorageAccessStatus.h"
    4242#include "WebCompiledContentRuleList.h"
     43#include "WebPageMessages.h"
    4344#include "WebPageProxy.h"
    4445#include "WebProcessMessages.h"
     
    269270        return;
    270271
    271     ASSERT_NOT_REACHED();
     272    didReceiveSyncNetworkProcessProxyMessage(connection, decoder, replyEncoder);
    272273}
    273274
     
    12041205}
    12051206
     1207void NetworkProcessProxy::testProcessIncomingSyncMessagesWhenWaitingForSyncReply(WebCore::PageIdentifier webPageID, Messages::NetworkProcessProxy::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::DelayedReply&& reply)
     1208{
     1209    auto* page = WebProcessProxy::webPage(webPageID);
     1210    if (!page)
     1211        return reply(false);
     1212
     1213    bool handled = false;
     1214    if (!page->sendSync(Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply(), Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::Reply(handled)))
     1215        return reply(false);
     1216    reply(handled);
     1217}
     1218
    12061219#if ENABLE(INDEXED_DATABASE)
    12071220void NetworkProcessProxy::createSymLinkForFileUpgrade(const String& indexedDatabaseDirectory)
  • branches/safari-608.1-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h

    r245796 r248349  
    164164    void didSyncAllCookies();
    165165
     166    void testProcessIncomingSyncMessagesWhenWaitingForSyncReply(WebCore::PageIdentifier, Messages::NetworkProcessProxy::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::DelayedReply&&);
     167
    166168    ProcessThrottler& throttler() { return m_throttler; }
    167169    WebProcessPool& processPool() { return m_processPool; }
     
    204206    void didClose(IPC::Connection&) override;
    205207    void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
     208    void didReceiveSyncNetworkProcessProxyMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&);
    206209
    207210    // Message handlers
  • branches/safari-608.1-branch/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in

    r245796 r248349  
    3131
    3232    DidSyncAllCookies()
     33
     34    TestProcessIncomingSyncMessagesWhenWaitingForSyncReply(WebCore::PageIdentifier webPageID) -> (bool handled) Synchronous
    3335
    3436    ProcessReadyToSuspend()
  • branches/safari-608.1-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp

    r246285 r248349  
    3737#include "InjectedBundleNodeHandle.h"
    3838#include "NavigationActionData.h"
     39#include "NetworkConnectionToWebProcessMessages.h"
     40#include "NetworkProcessConnection.h"
    3941#include "PageBanner.h"
    4042#include "UserData.h"
     
    304306}
    305307
     308bool WebChromeClient::testProcessIncomingSyncMessagesWhenWaitingForSyncReply()
     309{
     310    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        return false;
     313    return handled;
     314}
     315
    306316void WebChromeClient::show()
    307317{
     
    459469    HangDetectionDisabler hangDetectionDisabler;
    460470
    461     m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptAlert(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), alertText), Messages::WebPageProxy::RunJavaScriptAlert::Reply());
     471    m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptAlert(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), alertText), Messages::WebPageProxy::RunJavaScriptAlert::Reply(), IPC::SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply);
    462472}
    463473
     
    476486
    477487    bool result = false;
    478     if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptConfirm(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message), Messages::WebPageProxy::RunJavaScriptConfirm::Reply(result)))
     488    if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptConfirm(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message), Messages::WebPageProxy::RunJavaScriptConfirm::Reply(result), IPC::SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply))
    479489        return false;
    480490
     
    495505    HangDetectionDisabler hangDetectionDisabler;
    496506
    497     if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptPrompt(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message, defaultValue), Messages::WebPageProxy::RunJavaScriptPrompt::Reply(result)))
     507    if (!m_page.sendSyncWithDelayedReply(Messages::WebPageProxy::RunJavaScriptPrompt(webFrame->frameID(), SecurityOriginData::fromFrame(&frame), message, defaultValue), Messages::WebPageProxy::RunJavaScriptPrompt::Reply(result), IPC::SendSyncOption::ProcessIncomingSyncMessagesWhenWaitingForSyncReply))
    498508        return false;
    499509
  • branches/safari-608.1-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h

    r246285 r248349  
    223223    void contentRuleListNotification(const URL&, const WebCore::ContentRuleListResults&) final;
    224224
     225    bool testProcessIncomingSyncMessagesWhenWaitingForSyncReply() final;
     226
    225227#if PLATFORM(WIN)
    226228    void setLastSetCursorToCurrentCursor() final { }
  • branches/safari-608.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r247606 r248349  
    58755875}
    58765876
     5877void WebPage::testProcessIncomingSyncMessagesWhenWaitingForSyncReply(Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::DelayedReply&& reply)
     5878{
     5879    reply(true);
     5880}
     5881
    58775882#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
    58785883static const int primarySnapshottedPlugInSearchLimit = 3000;
  • branches/safari-608.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.h

    r247606 r248349  
    5050#include "UserData.h"
    5151#include "WebBackForwardListProxy.h"
     52#include "WebPageMessages.h"
    5253#include "WebURLSchemeHandler.h"
    5354#include "WebUndoStepID.h"
     
    11671168
    11681169    template<typename T>
    1169     bool sendSyncWithDelayedReply(T&& message, typename T::Reply&& reply)
     1170    bool sendSyncWithDelayedReply(T&& message, typename T::Reply&& reply, OptionSet<IPC::SendSyncOption> sendSyncOptions = { })
    11701171    {
    11711172        cancelGesturesBlockedOnSynchronousReplies();
    1172         return sendSync(WTFMove(message), WTFMove(reply), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend);
     1173        return sendSync(WTFMove(message), WTFMove(reply), Seconds::infinity(), sendSyncOptions | IPC::SendSyncOption::InformPlatformProcessWillSuspend);
    11731174    }
    11741175
     
    12881289    bool executeKeypressCommandsInternal(const Vector<WebCore::KeypressCommand>&, WebCore::KeyboardEvent*);
    12891290#endif
     1291
     1292    void testProcessIncomingSyncMessagesWhenWaitingForSyncReply(Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::DelayedReply&&);
    12901293
    12911294    void updateDrawingAreaLayerTreeFreezeState();
  • branches/safari-608.1-branch/Source/WebKit/WebProcess/WebPage/WebPage.messages.in

    r247597 r248349  
    3131    SendCSPViolationReport(uint64_t frameID, URL reportURL, IPC::FormDataReference reportData)
    3232    EnqueueSecurityPolicyViolationEvent(uint64_t frameID, WebCore::SecurityPolicyViolationEvent::Init eventInit)
     33
     34    TestProcessIncomingSyncMessagesWhenWaitingForSyncReply() -> (bool handled) Synchronous
    3335
    3436#if PLATFORM(COCOA)
Note: See TracChangeset for help on using the changeset viewer.