Chromium Code Reviews| Index: third_party/WebKit/Source/core/fetch/Resource.cpp |
| diff --git a/third_party/WebKit/Source/core/fetch/Resource.cpp b/third_party/WebKit/Source/core/fetch/Resource.cpp |
| index adf843dd7e9831f464f8fd72224979f566c5ea9f..d0ea83a07adf5a23cc137705c11a2b8d385ad486 100644 |
| --- a/third_party/WebKit/Source/core/fetch/Resource.cpp |
| +++ b/third_party/WebKit/Source/core/fetch/Resource.cpp |
| @@ -28,7 +28,7 @@ |
| #include "core/fetch/FetchInitiatorTypeNames.h" |
| #include "core/fetch/MemoryCache.h" |
| #include "core/fetch/ResourceClient.h" |
| -#include "core/fetch/ResourceClientOrObserverWalker.h" |
| +#include "core/fetch/ResourceClientWalker.h" |
| #include "core/fetch/ResourceLoader.h" |
| #include "core/inspector/InstanceCounters.h" |
| #include "platform/Histogram.h" |
| @@ -331,6 +331,9 @@ DEFINE_TRACE(Resource) |
| { |
| visitor->trace(m_loader); |
| visitor->trace(m_cacheHandler); |
| + visitor->trace(m_clients); |
| + visitor->trace(m_clientsAwaitingCallback); |
| + visitor->trace(m_finishedClients); |
| } |
| void Resource::setLoader(ResourceLoader* loader) |
| @@ -383,7 +386,7 @@ void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) |
| void Resource::markClientsAndObserversFinished() |
| { |
| - HashCountedSet<ResourceClient*> clients; |
| + HeapHashCountedSet<WeakMember<ResourceClient>> clients; |
| m_clients.swap(clients); |
| for (const auto& it : clients) |
| m_finishedClients.add(it.key, it.value); |
| @@ -719,7 +722,12 @@ void Resource::addClient(ResourceClient* client) |
| void Resource::removeClient(ResourceClient* client) |
| { |
| - ASSERT(hasClient(client)); |
| + if (!hasClient(client)) { |
|
haraken
2016/08/02 04:18:06
Would you help me understand when this can happen?
yhirano
2016/08/03 10:40:28
This function can be called from a pre-finalizer (
haraken
2016/08/03 11:11:40
Can we avoid calling Resource::removeClient() in t
haraken
2016/08/03 11:11:40
Can you avoid calling Resource::removeClient in th
yhirano
2016/08/09 07:38:21
It's hard because callers generally don't distingu
|
| + // In this case, the client is swept from client lists because they |
| + // hold clients as weak member. |
| + didRemoveClientOrObserver(); |
| + return; |
| + } |
| if (m_finishedClients.contains(client)) |
| m_finishedClients.remove(client); |
| else if (m_clientsAwaitingCallback.contains(client)) |
| @@ -731,7 +739,6 @@ void Resource::removeClient(ResourceClient* client) |
| ResourceCallback::callbackHandler().cancel(this); |
| didRemoveClientOrObserver(); |
| - // This object may be dead here. |
| } |
| void Resource::didRemoveClientOrObserver() |
| @@ -809,8 +816,13 @@ void Resource::finishPendingClients() |
| // Handle case (1) by saving a list of clients to notify. A separate list also ensure |
| // a client is either in m_clients or m_clientsAwaitingCallback. |
| - Vector<ResourceClient*> clientsToNotify; |
| - copyToVector(m_clientsAwaitingCallback, clientsToNotify); |
| + HeapVector<Member<ResourceClient>> clientsToNotify; |
| + clientsToNotify.reserveCapacity(m_clientsAwaitingCallback.size()); |
|
haraken
2016/08/02 04:18:06
Can we implement copyToVector for a hash counted s
yhirano
2016/08/03 10:40:28
We already have it, but as I said in the other pla
|
| + for (const auto& keyvalue : m_clientsAwaitingCallback) { |
| + ResourceClient* client = keyvalue.key; |
| + if (client) |
|
haraken
2016/08/02 04:18:06
I don't think this can happen. See my comment belo
yhirano
2016/08/03 10:40:28
Done.
|
| + clientsToNotify.append(client); |
| + } |
| for (const auto& client : clientsToNotify) { |
| // Handle case (2) to skip removed clients. |