Changeset 246452 in webkit


Ignore:
Timestamp:
Jun 14, 2019 6:07:16 PM (5 years ago)
Author:
youenn@apple.com
Message:

WebProcessPool::clearWebProcessHasUploads cannot assume its given processIdentifier is valid
https://bugs.webkit.org/show_bug.cgi?id=198865
<rdar://problem/51618878>

Reviewed by Brady Eidson.

NetworkProcess currently instructs UIProcess whether a given WebProcess is doing upload.
There is no guarantee though that the WebProcessProxy is still there when the IPC is arriving at UIProcess.
Instead, let WebProcess handles its upload state and notify WebProcessPool about its state.
Make sure WebProcessProxy unregisters itself in case of crash.
In case of NetworkProcess crash, WebProcesses will see all their uploads fail
and will notify automatically UIProcess to update their state.

Since the processID given to WebProcessPool is coming from IPC, we cannot not trust it.
Add early return in case of not finding a WebProcessProxy for WebProcessPool clear/set methods.

  • NetworkProcess/NetworkConnectionToWebProcess.cpp:

(WebKit::NetworkConnectionToWebProcess::NetworkConnectionToWebProcess):

  • NetworkProcess/NetworkConnectionToWebProcess.h:
  • NetworkProcess/NetworkConnectionToWebProcess.messages.in:
  • NetworkProcess/NetworkResourceLoadMap.cpp:

(WebKit::NetworkResourceLoadMap::add):
(WebKit::NetworkResourceLoadMap::take):

  • NetworkProcess/NetworkResourceLoadMap.h:
  • UIProcess/WebProcessPool.cpp:

(WebKit::WebProcessPool::setWebProcessHasUploads):
(WebKit::WebProcessPool::clearWebProcessHasUploads):

  • UIProcess/WebProcessProxy.cpp:

(WebKit::WebProcessProxy::~WebProcessProxy):

  • WebProcess/Network/WebLoaderStrategy.cpp:

(WebKit::WebLoaderStrategy::scheduleLoadFromNetworkProcess):
(WebKit::WebLoaderStrategy::remove):
(WebKit::WebLoaderStrategy::tryLoadingSynchronouslyUsingURLSchemeHandler):

  • WebProcess/Network/WebLoaderStrategy.h:
  • WebProcess/WebProcess.cpp:

(WebKit::WebProcess::ensureNetworkProcessConnection):

Location:
trunk/Source/WebKit
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r246449 r246452  
     12019-06-14  Youenn Fablet  <youenn@apple.com>
     2
     3        WebProcessPool::clearWebProcessHasUploads cannot assume its given processIdentifier is valid
     4        https://bugs.webkit.org/show_bug.cgi?id=198865
     5        <rdar://problem/51618878>
     6
     7        Reviewed by Brady Eidson.
     8
     9        NetworkProcess currently instructs UIProcess whether a given WebProcess is doing upload.
     10        There is no guarantee though that the WebProcessProxy is still there when the IPC is arriving at UIProcess.
     11        Instead, let WebProcess handles its upload state and notify WebProcessPool about its state.
     12        Make sure WebProcessProxy unregisters itself in case of crash.
     13        In case of NetworkProcess crash, WebProcesses will see all their uploads fail
     14        and will notify automatically UIProcess to update their state.
     15
     16        Since the processID given to WebProcessPool is coming from IPC, we cannot not trust it.
     17        Add early return in case of not finding a WebProcessProxy for WebProcessPool clear/set methods.
     18
     19        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     20        (WebKit::NetworkConnectionToWebProcess::NetworkConnectionToWebProcess):
     21        * NetworkProcess/NetworkConnectionToWebProcess.h:
     22        * NetworkProcess/NetworkConnectionToWebProcess.messages.in:
     23        * NetworkProcess/NetworkResourceLoadMap.cpp:
     24        (WebKit::NetworkResourceLoadMap::add):
     25        (WebKit::NetworkResourceLoadMap::take):
     26        * NetworkProcess/NetworkResourceLoadMap.h:
     27        * UIProcess/WebProcessPool.cpp:
     28        (WebKit::WebProcessPool::setWebProcessHasUploads):
     29        (WebKit::WebProcessPool::clearWebProcessHasUploads):
     30        * UIProcess/WebProcessProxy.cpp:
     31        (WebKit::WebProcessProxy::~WebProcessProxy):
     32        * WebProcess/Network/WebLoaderStrategy.cpp:
     33        (WebKit::WebLoaderStrategy::scheduleLoadFromNetworkProcess):
     34        (WebKit::WebLoaderStrategy::remove):
     35        (WebKit::WebLoaderStrategy::tryLoadingSynchronouslyUsingURLSchemeHandler):
     36        * WebProcess/Network/WebLoaderStrategy.h:
     37        * WebProcess/WebProcess.cpp:
     38        (WebKit::WebProcess::ensureNetworkProcessConnection):
     39
    1402019-06-14  Youenn Fablet  <youenn@apple.com>
    241
  • trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp

    r246388 r246452  
    8484    : m_connection(IPC::Connection::createServerConnection(connectionIdentifier, *this))
    8585    , m_networkProcess(networkProcess)
    86     , m_networkResourceLoaders(*this)
    8786#if ENABLE(WEB_RTC)
    8887    , m_mdnsRegister(*this)
     
    900899#endif
    901900
    902 void NetworkConnectionToWebProcess::setWebProcessIdentifier(ProcessIdentifier webProcessIdentifier)
    903 {
    904     m_webProcessIdentifier = webProcessIdentifier;
    905 }
    906 
    907 void NetworkConnectionToWebProcess::setConnectionHasUploads()
    908 {
    909     ASSERT(!m_connectionHasUploads);
    910     m_connectionHasUploads = true;
    911     m_networkProcess->parentProcessConnection()->send(Messages::WebProcessPool::SetWebProcessHasUploads(m_webProcessIdentifier), 0);
    912 }
    913 
    914 void NetworkConnectionToWebProcess::clearConnectionHasUploads()
    915 {
    916     ASSERT(m_connectionHasUploads);
    917     m_connectionHasUploads = false;
    918     m_networkProcess->parentProcessConnection()->send(Messages::WebProcessPool::ClearWebProcessHasUploads(m_webProcessIdentifier), 0);
    919 }
    920 
    921901void NetworkConnectionToWebProcess::webPageWasAdded(PAL::SessionID sessionID, PageIdentifier pageID, WebCore::PageIdentifier oldPageID)
    922902{
  • trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h

    r246388 r246452  
    143143    Vector<RefPtr<WebCore::BlobDataFileReference>> resolveBlobReferences(const NetworkResourceLoadParameters&);
    144144
    145     void setWebProcessIdentifier(WebCore::ProcessIdentifier);
    146     void setConnectionHasUploads();
    147     void clearConnectionHasUploads();
    148 
    149145    void webPageWasAdded(PAL::SessionID, WebCore::PageIdentifier, WebCore::PageIdentifier oldPageID);
    150146    void webPageWasRemoved(PAL::SessionID, WebCore::PageIdentifier);
     
    319315    std::unique_ptr<WebPaymentCoordinatorProxy> m_paymentCoordinator;
    320316#endif
    321 
    322     WebCore::ProcessIdentifier m_webProcessIdentifier;
    323     bool m_connectionHasUploads { false };
    324317};
    325318
  • trunk/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in

    r246388 r246452  
    8787#endif
    8888
    89     SetWebProcessIdentifier(WebCore::ProcessIdentifier processIdentifier)
    90 
    9189    WebPageWasAdded(PAL::SessionID sessionID, WebCore::PageIdentifier pageID, WebCore::PageIdentifier oldPageID)
    9290    WebPageWasRemoved(PAL::SessionID sessionID, WebCore::PageIdentifier pageID)
  • trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadMap.cpp

    r244700 r246452  
    2727#include "NetworkResourceLoadMap.h"
    2828
    29 #include "NetworkConnectionToWebProcess.h"
    30 
    3129namespace WebKit {
    3230
    3331NetworkResourceLoadMap::MapType::AddResult NetworkResourceLoadMap::add(ResourceLoadIdentifier identifier, Ref<NetworkResourceLoader>&& loader)
    3432{
    35     auto result = m_loaders.add(identifier, WTFMove(loader));
    36     ASSERT(result.isNewEntry);
    37        
    38     if (result.iterator->value->originalRequest().hasUpload()) {
    39         if (m_loadersWithUploads.isEmpty())
    40             m_connectionToWebProcess.setConnectionHasUploads();
    41         m_loadersWithUploads.add(result.iterator->value.ptr());
    42     }
    43 
    44     return result;
     33    ASSERT(!m_loaders.contains(identifier));
     34    return m_loaders.add(identifier, WTFMove(loader));
    4535}
    4636
     
    5545    if (!loader)
    5646        return nullptr;
    57 
    58     if ((*loader)->originalRequest().hasUpload()) {
    59         m_loadersWithUploads.remove(loader->ptr());
    60         if (m_loadersWithUploads.isEmpty())
    61             m_connectionToWebProcess.clearConnectionHasUploads();
    62     }
    63 
    6447    return WTFMove(*loader);
    6548}
  • trunk/Source/WebKit/NetworkProcess/NetworkResourceLoadMap.h

    r244700 r246452  
    4444    typedef HashMap<ResourceLoadIdentifier, Ref<NetworkResourceLoader>> MapType;
    4545
    46     NetworkResourceLoadMap(NetworkConnectionToWebProcess& connection)
    47         : m_connectionToWebProcess(connection)
    48     {
    49     }
    50 
    5146    bool isEmpty() const { return m_loaders.isEmpty(); }
    5247    bool contains(ResourceLoadIdentifier identifier) const { return m_loaders.contains(identifier); }
     
    6055
    6156private:
    62     NetworkConnectionToWebProcess& m_connectionToWebProcess;
    6357    MapType m_loaders;
    64     HashSet<NetworkResourceLoader*> m_loadersWithUploads;
    6558};
    6659
  • trunk/Source/WebKit/UIProcess/WebProcessPool.cpp

    r246328 r246452  
    25322532void WebProcessPool::setWebProcessHasUploads(ProcessIdentifier processID)
    25332533{
     2534    ASSERT(processID);
    25342535    auto* process = WebProcessProxy::processForIdentifier(processID);
    25352536    ASSERT(process);
     2537
     2538    if (!process)
     2539        return;
    25362540
    25372541    RELEASE_LOG(ProcessSuspension, "Web process pid %u now has uploads in progress", (unsigned)process->processIdentifier());
     
    25542558void WebProcessPool::clearWebProcessHasUploads(ProcessIdentifier processID)
    25552559{
     2560    ASSERT(processID);
    25562561    auto result = m_processesWithUploads.take(processID);
    2557     ASSERT_UNUSED(result, result);
     2562    ASSERT(result);
     2563    if (!result)
     2564        return;
    25582565
    25592566    auto* process = WebProcessProxy::processForIdentifier(processID);
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp

    r245868 r246452  
    169169    ASSERT(m_pageURLRetainCountMap.isEmpty());
    170170
     171    if (m_processPool)
     172        m_processPool->clearWebProcessHasUploads(coreProcessIdentifier());
     173
    171174    auto result = allProcesses().remove(coreProcessIdentifier());
    172175    ASSERT_UNUSED(result, result);
  • trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp

    r245979 r246452  
    4242#include "WebPageProxyMessages.h"
    4343#include "WebProcess.h"
     44#include "WebProcessPoolMessages.h"
    4445#include "WebResourceLoader.h"
    4546#include "WebServiceWorkerProvider.h"
     
    358359    }
    359360
    360     m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader, trackingParameters));
     361    auto loader = WebResourceLoader::create(resourceLoader, trackingParameters);
     362    if (resourceLoader.originalRequest().hasUpload()) {
     363        if (m_loadersWithUploads.isEmpty())
     364            WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessPool::SetWebProcessHasUploads(Process::identifier()), 0);
     365        m_loadersWithUploads.add(loader.ptr());
     366    }
     367
     368    m_webResourceLoaders.set(identifier, WTFMove(loader));
    361369}
    362370
     
    423431
    424432    WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::RemoveLoadIdentifier(identifier), 0);
     433
     434    if (m_loadersWithUploads.remove(loader.get()) && m_loadersWithUploads.isEmpty())
     435        WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessPool::ClearWebProcessHasUploads { Process::identifier() }, 0);
    425436
    426437    // It's possible that this WebResourceLoader might be just about to message back to the NetworkProcess (e.g. ContinueWillSendRequest)
     
    555566    HangDetectionDisabler hangDetectionDisabler;
    556567
     568    bool shouldNotifyOfUpload = request.hasUpload() && m_loadersWithUploads.isEmpty();
     569    if (shouldNotifyOfUpload)
     570        WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessPool::SetWebProcessHasUploads { Process::identifier() }, 0);
     571
    557572    if (!WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad(loadParameters), Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::Reply(error, response, data), 0)) {
    558573        RELEASE_LOG_ERROR_IF_ALLOWED(sessionID, "loadResourceSynchronously: failed sending synchronous network process message (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %lu)", pageID.toUInt64(), frameID, resourceLoadIdentifier);
     
    562577        error = internalError(request.url());
    563578    }
     579
     580    if (shouldNotifyOfUpload)
     581        WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessPool::ClearWebProcessHasUploads { Process::identifier() }, 0);
    564582}
    565583
  • trunk/Source/WebKit/WebProcess/Network/WebLoaderStrategy.h

    r245796 r246452  
    123123    Vector<Function<void(bool)>> m_onlineStateChangeListeners;
    124124    bool m_isOnLine { true };
     125    HashSet<WebResourceLoader*> m_loadersWithUploads;
    125126};
    126127
  • trunk/Source/WebKit/WebProcess/WebProcess.cpp

    r246388 r246452  
    12471247
    12481248        m_networkProcessConnection = NetworkProcessConnection::create(connectionIdentifier);
    1249         m_networkProcessConnection->connection().send(Messages::NetworkConnectionToWebProcess::SetWebProcessIdentifier(Process::identifier()), 0);
    12501249
    12511250        // To recover web storage, network process needs to know active webpages to prepare session storage.
Note: See TracChangeset for help on using the changeset viewer.