Index: Source/core/fetch/Resource.cpp |
diff --git a/Source/core/fetch/Resource.cpp b/Source/core/fetch/Resource.cpp |
index 936193b9f27e34bf19c43464216663076a2e5162..31d2d856e8afedeb617cf4350ac9f01458b828e1 100644 |
--- a/Source/core/fetch/Resource.cpp |
+++ b/Source/core/fetch/Resource.cpp |
@@ -563,12 +563,18 @@ void Resource::didAccessDecodedData() |
void Resource::finishPendingClients() |
{ |
- while (!m_clientsAwaitingCallback.isEmpty()) { |
- ResourceClient* client = m_clientsAwaitingCallback.begin()->key; |
- m_clientsAwaitingCallback.remove(client); |
- m_clients.add(client); |
- didAddClient(client); |
+ // Clients can be added during the loop. We must not process them now. |
+ // So save the current set to the stack. |
+ HashCountedSet<ResourceClient*> clientsAwaitingCallback; |
+ clientsAwaitingCallback.swap(m_clientsAwaitingCallback); |
+ |
+ for (HashCountedSet<ResourceClient*>::iterator it = clientsAwaitingCallback.begin(); it != clientsAwaitingCallback.end(); ++it) { |
+ m_clients.add(it->key); |
+ didAddClient(it->key); |
} |
+ // It is a critical problem if a callback is scheduled but there is no client waiting for it. |
+ // Such a callback cannot be cancelled. It is better to crash the renderer now. |
+ RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this) || !m_clientsAwaitingCallback.isEmpty()); |
} |
void Resource::prune() |