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

Changeset 137783 in webkit


Ignore:
Timestamp:
Dec 14, 2012, 3:33:45 PM (14 years ago)
Author:
ap@apple.com
Message:

<rdar://problem/12874760> NetworkProcess loads may get stuck when WebProcess quits
https://bugs.webkit.org/show_bug.cgi?id=105056

Reviewed by Anders Carlsson.

Make response maps per-connection.

  • NetworkProcess/NetworkConnectionToWebProcess.cpp: (WebKit::NetworkConnectionToWebProcess::didClose): Cancel waiting for responses from WebProcess, they will never arrive.
  • NetworkProcess/NetworkConnectionToWebProcess.h: (WebKit::NetworkConnectionToWebProcess::willSendRequestResponseMap): (WebKit::NetworkConnectionToWebProcess::canAuthenticateAgainstProtectionSpaceResponseMap): Maps now live here.
  • NetworkProcess/NetworkResourceLoader.cpp: (WebKit::NetworkResourceLoader::connectionToWebProcessDidClose): Added a FIXME.

(WebKit::NetworkResourceLoader::willSendRequest):
(WebKit::NetworkResourceLoader::willSendRequestHandled):
(WebKit::NetworkResourceLoader::canAuthenticateAgainstProtectionSpace):
(WebKit::NetworkResourceLoader::canAuthenticateAgainstProtectionSpaceHandled):
Handle the cases where we can't send a request, or can't expect a response any more.

  • Shared/BlockingResponseMap.h: (BlockingResponseMap): (BlockingResponseMap::BlockingResponseMap): (BlockingResponseMap::~BlockingResponseMap): (BlockingResponseMap::waitForResponse): (BlockingResponseMap::didReceiveResponse): (BlockingResponseMap::cancel): (BlockingBoolResponseMap): (BlockingBoolResponseMap::BlockingBoolResponseMap): (BlockingBoolResponseMap::~BlockingBoolResponseMap): (BlockingBoolResponseMap::waitForResponse): (BlockingBoolResponseMap::didReceiveResponse): (BlockingBoolResponseMap::cancel): Added an ability to cancel, and slightly beefed up overall.
Location:
trunk/Source/WebKit2
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r137768 r137783  
     12012-12-14  Alexey Proskuryakov  <ap@apple.com>
     2
     3        <rdar://problem/12874760> NetworkProcess loads may get stuck when WebProcess quits
     4        https://bugs.webkit.org/show_bug.cgi?id=105056
     5
     6        Reviewed by Anders Carlsson.
     7
     8        Make response maps per-connection.
     9
     10        * NetworkProcess/NetworkConnectionToWebProcess.cpp:
     11        (WebKit::NetworkConnectionToWebProcess::didClose): Cancel waiting for responses
     12        from WebProcess, they will never arrive.
     13
     14        * NetworkProcess/NetworkConnectionToWebProcess.h:
     15        (WebKit::NetworkConnectionToWebProcess::willSendRequestResponseMap):
     16        (WebKit::NetworkConnectionToWebProcess::canAuthenticateAgainstProtectionSpaceResponseMap):
     17        Maps now live here.
     18
     19        * NetworkProcess/NetworkResourceLoader.cpp:
     20        (WebKit::NetworkResourceLoader::connectionToWebProcessDidClose): Added a FIXME.
     21
     22        (WebKit::NetworkResourceLoader::willSendRequest):
     23        (WebKit::NetworkResourceLoader::willSendRequestHandled):
     24        (WebKit::NetworkResourceLoader::canAuthenticateAgainstProtectionSpace):
     25        (WebKit::NetworkResourceLoader::canAuthenticateAgainstProtectionSpaceHandled):
     26        Handle the cases where we can't send a request, or can't expect a response any more.
     27
     28        * Shared/BlockingResponseMap.h:
     29        (BlockingResponseMap):
     30        (BlockingResponseMap::BlockingResponseMap):
     31        (BlockingResponseMap::~BlockingResponseMap):
     32        (BlockingResponseMap::waitForResponse):
     33        (BlockingResponseMap::didReceiveResponse):
     34        (BlockingResponseMap::cancel):
     35        (BlockingBoolResponseMap):
     36        (BlockingBoolResponseMap::BlockingBoolResponseMap):
     37        (BlockingBoolResponseMap::~BlockingBoolResponseMap):
     38        (BlockingBoolResponseMap::waitForResponse):
     39        (BlockingBoolResponseMap::didReceiveResponse):
     40        (BlockingBoolResponseMap::cancel):
     41        Added an ability to cancel, and slightly beefed up overall.
     42
    1432012-12-14  Anders Carlsson  <andersca@apple.com>
    244
  • trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp

    r137657 r137783  
    103103   
    104104    NetworkProcess::shared().removeNetworkConnectionToWebProcess(this);
    105    
    106     // FIXME (NetworkProcess): We might consider actively clearing out all requests for this connection.
    107     // But that might not be necessary as the observer mechanism used above is much more direct.
     105
     106    // Unblock waiting threads.
     107    m_willSendRequestResponseMap.cancel();
     108    m_canAuthenticateAgainstProtectionSpaceResponseMap.cancel();
    108109
    109110    Vector<NetworkConnectionToWebProcessObserver*> observers;
  • trunk/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h

    r137647 r137783  
    2929#if ENABLE(NETWORK_PROCESS)
    3030
     31#include "BlockingResponseMap.h"
    3132#include "Connection.h"
    3233#include "NetworkConnectionToWebProcessMessages.h"
     
    6162
    6263    bool isSerialLoadingEnabled() const { return m_serialLoadingEnabled; }
     64
     65    BlockingResponseMap<WebCore::ResourceRequest*>& willSendRequestResponseMap() { return m_willSendRequestResponseMap; }
     66    BlockingBoolResponseMap& canAuthenticateAgainstProtectionSpaceResponseMap() { return m_canAuthenticateAgainstProtectionSpaceResponseMap; }
    6367
    6468private:
     
    96100   
    97101    HashSet<NetworkConnectionToWebProcessObserver*> m_observers;
    98    
     102
     103    BlockingResponseMap<WebCore::ResourceRequest*> m_willSendRequestResponseMap;
     104    BlockingBoolResponseMap m_canAuthenticateAgainstProtectionSpaceResponseMap;
     105
    99106    bool m_serialLoadingEnabled;
    100107};
  • trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp

    r137610 r137783  
    2929#if ENABLE(NETWORK_PROCESS)
    3030
    31 #include "BlockingResponseMap.h"
    3231#include "DataReference.h"
    3332#include "Logging.h"
     
    145144{
    146145    ASSERT_ARG(connection, connection == m_connection.get());
     146    // FIXME (NetworkProcess): Cancel the load. The request may be long-living, so we don't want it to linger around after all clients are gone.
    147147}
    148148
     
    178178}
    179179
    180 static BlockingResponseMap<ResourceRequest*>& willSendRequestResponseMap()
    181 {
    182     AtomicallyInitializedStatic(BlockingResponseMap<ResourceRequest*>&, responseMap = *new BlockingResponseMap<ResourceRequest*>);
    183     return responseMap;
    184 }
    185 
    186180static uint64_t generateWillSendRequestID()
    187181{
     
    192186void NetworkResourceLoader::willSendRequest(ResourceHandle*, ResourceRequest& request, const ResourceResponse& redirectResponse)
    193187{
    194     // We only expect to get the willSendRequest callback from ResourceHandle as the result of a redirect
     188    // We only expect to get the willSendRequest callback from ResourceHandle as the result of a redirect.
    195189    ASSERT(!redirectResponse.isNull());
    196190
    197191    uint64_t requestID = generateWillSendRequestID();
    198192
    199     send(Messages::WebResourceLoader::WillSendRequest(requestID, request, redirectResponse));
    200    
    201     OwnPtr<ResourceRequest> newRequest = willSendRequestResponseMap().waitForResponse(requestID);
    202     request = *newRequest;
     193    if (!send(Messages::WebResourceLoader::WillSendRequest(requestID, request, redirectResponse))) {
     194        request = ResourceRequest();
     195        return;
     196    }
     197
     198    OwnPtr<ResourceRequest> newRequest = m_connection->willSendRequestResponseMap().waitForResponse(requestID);
     199    request = newRequest ? *newRequest : ResourceRequest();
    203200
    204201    RunLoop::main()->dispatch(WTF::bind(&NetworkResourceLoadScheduler::receivedRedirect, &NetworkProcess::shared().networkResourceLoadScheduler(), m_identifier, request.url()));
     
    207204void NetworkResourceLoader::willSendRequestHandled(uint64_t requestID, const WebCore::ResourceRequest& newRequest)
    208205{
    209     willSendRequestResponseMap().didReceiveResponse(requestID, adoptPtr(new ResourceRequest(newRequest)));
     206    m_connection->willSendRequestResponseMap().didReceiveResponse(requestID, adoptPtr(new ResourceRequest(newRequest)));
    210207}
    211208
     
    301298
    302299#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
    303 static BlockingBoolResponseMap& canAuthenticateAgainstProtectionSpaceResponseMap()
    304 {
    305     AtomicallyInitializedStatic(BlockingBoolResponseMap&, responseMap = *new BlockingBoolResponseMap);
    306     return responseMap;
    307 }
    308 
    309300static uint64_t generateCanAuthenticateAgainstProtectionSpaceID()
    310301{
     
    317308    uint64_t requestID = generateCanAuthenticateAgainstProtectionSpaceID();
    318309
    319     send(Messages::WebResourceLoader::CanAuthenticateAgainstProtectionSpace(requestID, protectionSpace));
    320 
    321     return canAuthenticateAgainstProtectionSpaceResponseMap().waitForResponse(requestID);
     310    if (!send(Messages::WebResourceLoader::CanAuthenticateAgainstProtectionSpace(requestID, protectionSpace)))
     311        return false;
     312
     313    return m_connection->canAuthenticateAgainstProtectionSpaceResponseMap().waitForResponse(requestID);
    322314}
    323315
    324316void NetworkResourceLoader::canAuthenticateAgainstProtectionSpaceHandled(uint64_t requestID, bool canAuthenticate)
    325317{
    326     canAuthenticateAgainstProtectionSpaceResponseMap().didReceiveResponse(requestID, canAuthenticate);
     318    m_connection->canAuthenticateAgainstProtectionSpaceResponseMap().didReceiveResponse(requestID, canAuthenticate);
    327319}
    328320#endif
  • trunk/Source/WebKit2/Shared/BlockingResponseMap.h

    r137766 r137783  
    3434template<typename T>
    3535class BlockingResponseMap {
     36WTF_MAKE_NONCOPYABLE(BlockingResponseMap);
    3637public:
     38    BlockingResponseMap() : m_canceled(false) { }
     39    ~BlockingResponseMap() { ASSERT(m_responses.isEmpty()); }
     40
    3741    PassOwnPtr<T> waitForResponse(uint64_t requestID)
    3842    {
    3943        while (true) {
    4044            MutexLocker locker(m_mutex);
     45
     46            if (m_canceled)
     47                return nullptr;
    4148
    4249            if (OwnPtr<T> response = m_responses.take(requestID))
     
    5562
    5663        m_responses.set(requestID, response);
    57         // FIXME (NetworkProcess): Waking up all threads is quite inefficient.
     64        // FIXME (NetworkProcess): <rdar://problem/12886430>: Waking up all threads is quite inefficient.
     65        m_condition.broadcast();
     66    }
     67
     68    void cancel()
     69    {
     70        m_canceled = true;
     71
     72        // FIXME (NetworkProcess): <rdar://problem/12886430>: Waking up all threads is quite inefficient.
    5873        m_condition.broadcast();
    5974    }
     
    6479
    6580    HashMap<uint64_t, OwnPtr<T> > m_responses;
     81    bool m_canceled;
    6682};
    6783
    6884class BlockingBoolResponseMap {
     85WTF_MAKE_NONCOPYABLE(BlockingBoolResponseMap);
    6986public:
     87    BlockingBoolResponseMap() : m_canceled(false) { }
     88    ~BlockingBoolResponseMap() { ASSERT(m_responses.isEmpty()); }
     89
    7090    bool waitForResponse(uint64_t requestID)
    7191    {
    7292        while (true) {
    7393            MutexLocker locker(m_mutex);
     94
     95            // FIXME: Differentiate between canceled wait and a negative response.
     96            if (m_canceled)
     97                return false;
    7498
    7599            HashMap<uint64_t, bool>::iterator iter = m_responses.find(requestID);
     
    92116
    93117        m_responses.set(requestID, response);
    94         // FIXME (NetworkProcess): Waking up all threads is quite inefficient.
     118        // FIXME (NetworkProcess): <rdar://problem/12886430>: Waking up all threads is quite inefficient.
     119        m_condition.broadcast();
     120    }
     121
     122    void cancel()
     123    {
     124        m_canceled = true;
     125
     126        // FIXME (NetworkProcess): <rdar://problem/12886430>: Waking up all threads is quite inefficient.
    95127        m_condition.broadcast();
    96128    }
     
    101133
    102134    HashMap<uint64_t, bool> m_responses;
     135    bool m_canceled;
    103136};
    104137
Note: See TracChangeset for help on using the changeset viewer.