Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: Source/core/fetch/Resource.cpp

Issue 1237983003: Revalidate using the same Resource, attempt #2 (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/fetch/Resource.h ('k') | Source/core/fetch/ResourceFetcher.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
6 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 6 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
7 7
8 This library is free software; you can redistribute it and/or 8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public 9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either 10 License as published by the Free Software Foundation; either
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 , m_requestedFromNetworkingLayer(false) 161 , m_requestedFromNetworkingLayer(false)
162 , m_loading(false) 162 , m_loading(false)
163 , m_switchingClientsToRevalidatedResource(false) 163 , m_switchingClientsToRevalidatedResource(false)
164 , m_type(type) 164 , m_type(type)
165 , m_status(Pending) 165 , m_status(Pending)
166 , m_wasPurged(false) 166 , m_wasPurged(false)
167 , m_needsSynchronousCacheHit(false) 167 , m_needsSynchronousCacheHit(false)
168 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK 168 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
169 , m_deleted(false) 169 , m_deleted(false)
170 #endif 170 #endif
171 , m_resourceToRevalidate(nullptr)
172 , m_proxyResource(nullptr)
173 { 171 {
174 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car eless updates of the enum. 172 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car eless updates of the enum.
175 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); 173 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter);
176 #ifndef NDEBUG 174 #ifndef NDEBUG
177 cachedResourceLeakCounter.increment(); 175 cachedResourceLeakCounter.increment();
178 #endif 176 #endif
179 memoryCache()->registerLiveResource(*this); 177 memoryCache()->registerLiveResource(*this);
180 178
181 // Currently we support the metadata caching only for HTTP family. 179 // Currently we support the metadata caching only for HTTP family.
182 if (m_resourceRequest.url().protocolIsInHTTPFamily()) 180 if (m_resourceRequest.url().protocolIsInHTTPFamily())
183 m_cacheHandler = CacheHandler::create(this); 181 m_cacheHandler = CacheHandler::create(this);
184 182
185 if (!m_resourceRequest.url().hasFragmentIdentifier()) 183 if (!m_resourceRequest.url().hasFragmentIdentifier())
186 return; 184 return;
187 KURL urlForCache = MemoryCache::removeFragmentIdentifierIfNeeded(m_resourceR equest.url()); 185 KURL urlForCache = MemoryCache::removeFragmentIdentifierIfNeeded(m_resourceR equest.url());
188 if (urlForCache.hasFragmentIdentifier()) 186 if (urlForCache.hasFragmentIdentifier())
189 return; 187 return;
190 m_fragmentIdentifierForRequest = m_resourceRequest.url().fragmentIdentifier( ); 188 m_fragmentIdentifierForRequest = m_resourceRequest.url().fragmentIdentifier( );
191 m_resourceRequest.setURL(urlForCache); 189 m_resourceRequest.setURL(urlForCache);
192 } 190 }
193 191
194 Resource::~Resource() 192 Resource::~Resource()
195 { 193 {
196 ASSERT(!m_resourceToRevalidate); // Should be true because canDelete() check s this.
197 ASSERT(canDelete()); 194 ASSERT(canDelete());
198 RELEASE_ASSERT(!memoryCache()->contains(this)); 195 RELEASE_ASSERT(!memoryCache()->contains(this));
199 RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this)); 196 RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this));
200 assertAlive(); 197 assertAlive();
201 198
202 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK 199 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
203 m_deleted = true; 200 m_deleted = true;
204 #endif 201 #endif
205 #ifndef NDEBUG 202 #ifndef NDEBUG
206 cachedResourceLeakCounter.decrement(); 203 cachedResourceLeakCounter.decrement();
207 #endif 204 #endif
208 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); 205 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter);
209 } 206 }
210 207
211 void Resource::dispose() 208 void Resource::dispose()
212 { 209 {
213 } 210 }
214 211
215 DEFINE_TRACE(Resource) 212 DEFINE_TRACE(Resource)
216 { 213 {
217 visitor->trace(m_loader); 214 visitor->trace(m_loader);
218 visitor->trace(m_resourceToRevalidate);
219 visitor->trace(m_proxyResource);
220 #if ENABLE(OILPAN) 215 #if ENABLE(OILPAN)
221 visitor->trace(m_cacheHandler); 216 visitor->trace(m_cacheHandler);
222 #endif 217 #endif
223 } 218 }
224 219
225 void Resource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions& optio ns) 220 void Resource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions& optio ns)
226 { 221 {
227 m_options = options; 222 m_options = options;
228 m_loading = true; 223 m_loading = true;
229 224
225 ResourceRequest request(m_revalidatingRequest.isNull() ? m_resourceRequest : m_revalidatingRequest);
230 if (!accept().isEmpty()) 226 if (!accept().isEmpty())
231 m_resourceRequest.setHTTPAccept(accept()); 227 request.setHTTPAccept(accept());
232 228
233 // FIXME: It's unfortunate that the cache layer and below get to know anythi ng about fragment identifiers. 229 // FIXME: It's unfortunate that the cache layer and below get to know anythi ng about fragment identifiers.
234 // We should look into removing the expectation of that knowledge from the p latform network stacks. 230 // We should look into removing the expectation of that knowledge from the p latform network stacks.
235 ResourceRequest request(m_resourceRequest);
236 if (!m_fragmentIdentifierForRequest.isNull()) { 231 if (!m_fragmentIdentifierForRequest.isNull()) {
237 KURL url = request.url(); 232 KURL url = request.url();
238 url.setFragmentIdentifier(m_fragmentIdentifierForRequest); 233 url.setFragmentIdentifier(m_fragmentIdentifierForRequest);
239 request.setURL(url); 234 request.setURL(url);
240 m_fragmentIdentifierForRequest = String(); 235 m_fragmentIdentifierForRequest = String();
241 } 236 }
242 m_status = Pending; 237 m_status = Pending;
243 if (m_loader) { 238 if (m_loader) {
239 ASSERT(m_revalidatingRequest.isNull());
244 RELEASE_ASSERT(m_options.synchronousPolicy == RequestSynchronously); 240 RELEASE_ASSERT(m_options.synchronousPolicy == RequestSynchronously);
245 m_loader->changeToSynchronous(); 241 m_loader->changeToSynchronous();
246 return; 242 return;
247 } 243 }
248 m_loader = ResourceLoader::create(fetcher, this, request, options); 244 m_loader = ResourceLoader::create(fetcher, this, request, options);
249 m_loader->start(); 245 m_loader->start();
250 } 246 }
251 247
252 void Resource::checkNotify() 248 void Resource::checkNotify()
253 { 249 {
254 if (isLoading()) 250 if (isLoading())
255 return; 251 return;
256 252
257 ResourceClientWalker<ResourceClient> w(m_clients); 253 ResourceClientWalker<ResourceClient> w(m_clients);
258 while (ResourceClient* c = w.next()) 254 while (ResourceClient* c = w.next())
259 c->notifyFinished(this); 255 c->notifyFinished(this);
260 } 256 }
261 257
262 void Resource::appendData(const char* data, unsigned length) 258 void Resource::appendData(const char* data, unsigned length)
263 { 259 {
264 TRACE_EVENT0("blink", "Resource::appendData"); 260 TRACE_EVENT0("blink", "Resource::appendData");
265 ASSERT(!m_resourceToRevalidate); 261 ASSERT(m_revalidatingRequest.isNull());
266 ASSERT(!errorOccurred()); 262 ASSERT(!errorOccurred());
267 if (m_options.dataBufferingPolicy == DoNotBufferData) 263 if (m_options.dataBufferingPolicy == DoNotBufferData)
268 return; 264 return;
269 if (m_data) 265 if (m_data)
270 m_data->append(data, length); 266 m_data->append(data, length);
271 else 267 else
272 m_data = SharedBuffer::createPurgeable(data, length); 268 m_data = SharedBuffer::createPurgeable(data, length);
273 setEncodedSize(m_data->size()); 269 setEncodedSize(m_data->size());
274 } 270 }
275 271
276 void Resource::setResourceBuffer(PassRefPtr<SharedBuffer> resourceBuffer) 272 void Resource::setResourceBuffer(PassRefPtr<SharedBuffer> resourceBuffer)
277 { 273 {
278 ASSERT(!m_resourceToRevalidate); 274 ASSERT(m_revalidatingRequest.isNull());
279 ASSERT(!errorOccurred()); 275 ASSERT(!errorOccurred());
280 ASSERT(m_options.dataBufferingPolicy == BufferData); 276 ASSERT(m_options.dataBufferingPolicy == BufferData);
281 m_data = resourceBuffer; 277 m_data = resourceBuffer;
282 setEncodedSize(m_data->size()); 278 setEncodedSize(m_data->size());
283 } 279 }
284 280
285 void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) 281 void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy)
286 { 282 {
287 m_options.dataBufferingPolicy = dataBufferingPolicy; 283 m_options.dataBufferingPolicy = dataBufferingPolicy;
288 m_data.clear(); 284 m_data.clear();
289 setEncodedSize(0); 285 setEncodedSize(0);
290 } 286 }
291 287
292 void Resource::error(Resource::Status status) 288 void Resource::error(Resource::Status status)
293 { 289 {
294 if (m_resourceToRevalidate) 290 if (!m_revalidatingRequest.isNull())
295 revalidationFailed(); 291 m_revalidatingRequest = ResourceRequest();
Nate Chapin 2015/07/16 23:35:27 The only difference between this and the original
Yoav Weiss 2015/07/17 08:57:03 Do we have tests that caught this logic change?
296 292
297 if (!m_error.isNull() && (m_error.isCancellation() || !isPreloaded())) 293 if (!m_error.isNull() && (m_error.isCancellation() || !isPreloaded()))
298 memoryCache()->remove(this); 294 memoryCache()->remove(this);
299 295
300 setStatus(status); 296 setStatus(status);
301 ASSERT(errorOccurred()); 297 ASSERT(errorOccurred());
302 m_data.clear(); 298 m_data.clear();
303 299
304 setLoading(false); 300 setLoading(false);
305 checkNotify(); 301 checkNotify();
306 } 302 }
307 303
308 void Resource::finishOnePart() 304 void Resource::finishOnePart()
309 { 305 {
310 setLoading(false); 306 setLoading(false);
311 checkNotify(); 307 checkNotify();
312 } 308 }
313 309
314 void Resource::finish() 310 void Resource::finish()
315 { 311 {
316 ASSERT(!m_resourceToRevalidate); 312 ASSERT(m_revalidatingRequest.isNull());
317 ASSERT(!errorOccurred()); 313 ASSERT(!errorOccurred());
318 finishOnePart(); 314 finishOnePart();
319 if (!errorOccurred()) 315 if (!errorOccurred())
320 m_status = Cached; 316 m_status = Cached;
321 } 317 }
322 318
323 bool Resource::passesAccessControlCheck(SecurityOrigin* securityOrigin) const 319 bool Resource::passesAccessControlCheck(SecurityOrigin* securityOrigin) const
324 { 320 {
325 String ignoredErrorDescription; 321 String ignoredErrorDescription;
326 return passesAccessControlCheck(securityOrigin, ignoredErrorDescription); 322 return passesAccessControlCheck(securityOrigin, ignoredErrorDescription);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 } 429 }
434 430
435 bool Resource::unlock() 431 bool Resource::unlock()
436 { 432 {
437 if (!m_data) 433 if (!m_data)
438 return false; 434 return false;
439 435
440 if (!m_data->isLocked()) 436 if (!m_data->isLocked())
441 return true; 437 return true;
442 438
443 if (!memoryCache()->contains(this) || hasClients() || m_handleCount > 1 || m _proxyResource || m_resourceToRevalidate || !m_loadFinishTime || !isSafeToUnlock ()) 439 if (!memoryCache()->contains(this) || hasClients() || m_handleCount > 1 || ! m_revalidatingRequest.isNull() || !m_loadFinishTime || !isSafeToUnlock())
444 return false; 440 return false;
445 441
446 m_data->unlock(); 442 m_data->unlock();
447 return true; 443 return true;
448 } 444 }
449 445
450 bool Resource::hasRightHandleCountApartFromCache(unsigned targetCount) const 446 bool Resource::hasRightHandleCountApartFromCache(unsigned targetCount) const
451 { 447 {
452 return m_handleCount == targetCount + (memoryCache()->contains(this) ? 1 : 0 ); 448 return m_handleCount == targetCount + (memoryCache()->contains(this) ? 1 : 0 );
453 } 449 }
454 450
455 void Resource::responseReceived(const ResourceResponse& response, PassOwnPtr<Web DataConsumerHandle>) 451 void Resource::responseReceived(const ResourceResponse& response, PassOwnPtr<Web DataConsumerHandle>)
456 { 452 {
453 m_responseTimestamp = currentTime();
454
455 if (!m_revalidatingRequest.isNull()) {
456 if (response.httpStatusCode() == 304) {
457 revalidationSucceeded(response);
458 return;
459 }
460 revalidationFailed();
461 }
462
457 setResponse(response); 463 setResponse(response);
458 m_responseTimestamp = currentTime();
459 String encoding = response.textEncodingName(); 464 String encoding = response.textEncodingName();
460 if (!encoding.isNull()) 465 if (!encoding.isNull())
461 setEncoding(encoding); 466 setEncoding(encoding);
462
463 if (!m_resourceToRevalidate)
464 return;
465 if (response.httpStatusCode() == 304)
466 revalidationSucceeded(response);
467 else
468 revalidationFailed();
469 } 467 }
470 468
471 void Resource::setSerializedCachedMetadata(const char* data, size_t size) 469 void Resource::setSerializedCachedMetadata(const char* data, size_t size)
472 { 470 {
473 // We only expect to receive cached metadata from the platform once. 471 // We only expect to receive cached metadata from the platform once.
474 // If this triggers, it indicates an efficiency problem which is most 472 // If this triggers, it indicates an efficiency problem which is most
475 // likely unexpected in code designed to improve performance. 473 // likely unexpected in code designed to improve performance.
476 ASSERT(!m_cachedMetadata); 474 ASSERT(!m_cachedMetadata);
477 ASSERT(!m_resourceToRevalidate); 475 ASSERT(m_revalidatingRequest.isNull());
478 476
479 m_cachedMetadata = CachedMetadata::deserialize(data, size); 477 m_cachedMetadata = CachedMetadata::deserialize(data, size);
480 } 478 }
481 479
482 CachedMetadataHandler* Resource::cacheHandler() 480 CachedMetadataHandler* Resource::cacheHandler()
483 { 481 {
484 return m_cacheHandler.get(); 482 return m_cacheHandler.get();
485 } 483 }
486 484
487 void Resource::setCachedMetadata(unsigned dataTypeID, const char* data, size_t s ize, CachedMetadataHandler::CacheType cacheType) 485 void Resource::setCachedMetadata(unsigned dataTypeID, const char* data, size_t s ize, CachedMetadataHandler::CacheType cacheType)
(...skipping 20 matching lines...) Expand all
508 { 506 {
509 m_cachedMetadata.clear(); 507 m_cachedMetadata.clear();
510 508
511 if (cacheType == CachedMetadataHandler::SendToPlatform) 509 if (cacheType == CachedMetadataHandler::SendToPlatform)
512 Platform::current()->cacheMetadata(m_response.url(), m_response.response Time(), 0, 0); 510 Platform::current()->cacheMetadata(m_response.url(), m_response.response Time(), 0, 0);
513 } 511 }
514 512
515 bool Resource::canDelete() const 513 bool Resource::canDelete() const
516 { 514 {
517 return !hasClients() && !m_loader && !m_preloadCount && hasRightHandleCountA partFromCache(0) 515 return !hasClients() && !m_loader && !m_preloadCount && hasRightHandleCountA partFromCache(0)
518 && !m_protectorCount && !m_resourceToRevalidate && !m_proxyResource; 516 && !m_protectorCount;
519 } 517 }
520 518
521 bool Resource::hasOneHandle() const 519 bool Resource::hasOneHandle() const
522 { 520 {
523 return hasRightHandleCountApartFromCache(1); 521 return hasRightHandleCountApartFromCache(1);
524 } 522 }
525 523
526 CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const 524 CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const
527 { 525 {
528 if (!m_cachedMetadata || m_cachedMetadata->dataTypeID() != dataTypeID) 526 if (!m_cachedMetadata || m_cachedMetadata->dataTypeID() != dataTypeID)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 m_preloadResult = PreloadReferencedWhileComplete; 573 m_preloadResult = PreloadReferencedWhileComplete;
576 else if (m_requestedFromNetworkingLayer) 574 else if (m_requestedFromNetworkingLayer)
577 m_preloadResult = PreloadReferencedWhileLoading; 575 m_preloadResult = PreloadReferencedWhileLoading;
578 else 576 else
579 m_preloadResult = PreloadReferenced; 577 m_preloadResult = PreloadReferenced;
580 } 578 }
581 if (!hasClients()) 579 if (!hasClients())
582 memoryCache()->makeLive(this); 580 memoryCache()->makeLive(this);
583 581
584 // If we have existing data to send to the new client and the resource type supprts it, send it asynchronously. 582 // If we have existing data to send to the new client and the resource type supprts it, send it asynchronously.
585 if (!m_response.isNull() && !m_proxyResource && !shouldSendCachedDataSynchro nouslyForType(type()) && !m_needsSynchronousCacheHit) { 583 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(type() ) && !m_needsSynchronousCacheHit) {
586 m_clientsAwaitingCallback.add(client); 584 m_clientsAwaitingCallback.add(client);
587 ResourceCallback::callbackHandler()->schedule(this); 585 ResourceCallback::callbackHandler()->schedule(this);
588 return false; 586 return false;
589 } 587 }
590 588
591 m_clients.add(client); 589 m_clients.add(client);
592 return true; 590 return true;
593 } 591 }
594 592
595 void Resource::removeClient(ResourceClient* client) 593 void Resource::removeClient(ResourceClient* client)
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 // Prevent the case when there are clients waiting but no callback scheduled . 717 // Prevent the case when there are clients waiting but no callback scheduled .
720 ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled); 718 ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled);
721 } 719 }
722 720
723 void Resource::prune() 721 void Resource::prune()
724 { 722 {
725 destroyDecodedDataIfPossible(); 723 destroyDecodedDataIfPossible();
726 unlock(); 724 unlock();
727 } 725 }
728 726
729 void Resource::setResourceToRevalidate(Resource* resource) 727
728 void Resource::revalidationSucceeded(const ResourceResponse& validatingResponse)
730 { 729 {
731 ASSERT(resource); 730 // Calling evict() can potentially delete revalidatingResource, which we use
732 ASSERT(!m_resourceToRevalidate); 731 // below. This mustn't be the case since revalidation means it is loaded
733 ASSERT(resource != this); 732 // and so canDelete() is false.
734 ASSERT(m_handlesToRevalidate.isEmpty()); 733 ASSERT(!canDelete());
735 ASSERT(resource->type() == type());
736 734
737 WTF_LOG(ResourceLoading, "Resource %p setResourceToRevalidate %p", this, res ource);
738
739 // The following assert should be investigated whenever it occurs. Although it should never fire, it currently does in rare circumstances.
740 // https://bugs.webkit.org/show_bug.cgi?id=28604.
741 // So the code needs to be robust to this assert failing thus the "if (m_res ourceToRevalidate->m_proxyResource == this)" in Resource::clearResourceToRevalid ate.
742 ASSERT(!resource->m_proxyResource);
743
744 resource->m_proxyResource = this;
745 m_resourceToRevalidate = resource;
746 }
747
748 void Resource::clearResourceToRevalidate()
749 {
750 ASSERT(m_resourceToRevalidate);
751 if (m_switchingClientsToRevalidatedResource)
752 return;
753
754 // A resource may start revalidation before this method has been called, so check that this resource is still the proxy resource before clearing it out.
755 if (m_resourceToRevalidate->m_proxyResource == this) {
756 m_resourceToRevalidate->m_proxyResource = nullptr;
757 m_resourceToRevalidate->deleteIfPossible();
758 }
759 m_handlesToRevalidate.clear();
760 m_resourceToRevalidate = nullptr;
761 deleteIfPossible();
762 }
763
764 void Resource::switchClientsToRevalidatedResource()
765 {
766 ASSERT(m_resourceToRevalidate);
767 ASSERT(memoryCache()->contains(m_resourceToRevalidate));
768 ASSERT(!memoryCache()->contains(this));
769
770 WTF_LOG(ResourceLoading, "Resource %p switchClientsToRevalidatedResource %p" , this, m_resourceToRevalidate.get());
771
772 m_resourceToRevalidate->m_identifier = m_identifier;
773
774 m_switchingClientsToRevalidatedResource = true;
775 for (ResourcePtrBase* handle : m_handlesToRevalidate) {
776 handle->m_resource = m_resourceToRevalidate;
777 m_resourceToRevalidate->registerHandle(handle);
778 --m_handleCount;
779 }
780 ASSERT(!m_handleCount);
781 m_handlesToRevalidate.clear();
782
783 Vector<ResourceClient*> clientsToMove;
784 for (const auto& clientHashEntry : m_clients) {
785 unsigned count = clientHashEntry.value;
786 while (count--)
787 clientsToMove.append(clientHashEntry.key);
788 }
789
790 unsigned moveCount = clientsToMove.size();
791 for (unsigned n = 0; n < moveCount; ++n)
792 removeClient(clientsToMove[n]);
793 ASSERT(m_clients.isEmpty());
794
795 for (unsigned n = 0; n < moveCount; ++n)
796 m_resourceToRevalidate->addClientToSet(clientsToMove[n]);
797 for (unsigned n = 0; n < moveCount; ++n) {
798 // Calling didAddClient may do anything, including trying to cancel reva lidation.
799 // Assert that it didn't succeed.
800 ASSERT(m_resourceToRevalidate);
801 // Calling didAddClient for a client may end up removing another client. In that case it won't be in the set anymore.
802 if (m_resourceToRevalidate->m_clients.contains(clientsToMove[n]))
803 m_resourceToRevalidate->didAddClient(clientsToMove[n]);
804 }
805 m_switchingClientsToRevalidatedResource = false;
806 }
807
808 void Resource::updateResponseAfterRevalidation(const ResourceResponse& validatin gResponse)
809 {
810 m_responseTimestamp = currentTime(); 735 m_responseTimestamp = currentTime();
736 m_response.setResourceLoadTiming(validatingResponse.resourceLoadTiming());
811 737
812 // RFC2616 10.3.5 738 // RFC2616 10.3.5
813 // Update cached headers from the 304 response 739 // Update cached headers from the 304 response
814 const HTTPHeaderMap& newHeaders = validatingResponse.httpHeaderFields(); 740 const HTTPHeaderMap& newHeaders = validatingResponse.httpHeaderFields();
815 for (const auto& header : newHeaders) { 741 for (const auto& header : newHeaders) {
816 // Entity headers should not be sent by servers when generating a 304 742 // Entity headers should not be sent by servers when generating a 304
817 // response; misconfigured servers send them anyway. We shouldn't allow 743 // response; misconfigured servers send them anyway. We shouldn't allow
818 // such headers to update the original request. We'll base this on the 744 // such headers to update the original request. We'll base this on the
819 // list defined by RFC2616 7.1, with a few additions for extension heade rs 745 // list defined by RFC2616 7.1, with a few additions for extension heade rs
820 // we care about. 746 // we care about.
821 if (!shouldUpdateHeaderAfterRevalidation(header.key)) 747 if (!shouldUpdateHeaderAfterRevalidation(header.key))
822 continue; 748 continue;
823 m_response.setHTTPHeaderField(header.key, header.value); 749 m_response.setHTTPHeaderField(header.key, header.value);
824 } 750 }
825 }
826 751
827 void Resource::revalidationSucceeded(const ResourceResponse& response)
828 {
829 ASSERT(m_resourceToRevalidate);
830 ASSERT(!memoryCache()->contains(m_resourceToRevalidate));
831 ASSERT(m_resourceToRevalidate->isLoaded());
832
833 // Calling evict() can potentially delete revalidatingResource, which we use
834 // below. This mustn't be the case since revalidation means it is loaded
835 // and so canDelete() is false.
836 ASSERT(!canDelete());
837
838 m_resourceToRevalidate->updateResponseAfterRevalidation(response);
839 memoryCache()->replace(m_resourceToRevalidate, this);
840
841 switchClientsToRevalidatedResource();
842 assertAlive(); 752 assertAlive();
843 // clearResourceToRevalidate deletes this. 753 m_resourceRequest = m_revalidatingRequest;
844 clearResourceToRevalidate(); 754 m_revalidatingRequest = ResourceRequest();
845 } 755 }
846 756
847 void Resource::revalidationFailed() 757 void Resource::revalidationFailed()
848 { 758 {
849 ASSERT(WTF::isMainThread()); 759 m_resourceRequest = m_revalidatingRequest;
850 WTF_LOG(ResourceLoading, "Revalidation failed for %p", this); 760 m_revalidatingRequest = ResourceRequest();
851 ASSERT(resourceToRevalidate()); 761 m_data.clear();
852 clearResourceToRevalidate(); 762 destroyDecodedDataForFailedRevalidation();
853 } 763 }
854 764
855 void Resource::registerHandle(ResourcePtrBase* h) 765 void Resource::registerHandle(ResourcePtrBase* h)
856 { 766 {
857 assertAlive(); 767 assertAlive();
858 ++m_handleCount; 768 ++m_handleCount;
859 if (m_resourceToRevalidate)
860 m_handlesToRevalidate.add(h);
861 } 769 }
862 770
863 void Resource::unregisterHandle(ResourcePtrBase* h) 771 void Resource::unregisterHandle(ResourcePtrBase* h)
864 { 772 {
865 assertAlive(); 773 assertAlive();
866 ASSERT(m_handleCount > 0); 774 ASSERT(m_handleCount > 0);
867 --m_handleCount; 775 --m_handleCount;
868 776
869 if (m_resourceToRevalidate)
870 m_handlesToRevalidate.remove(h);
871
872 if (!m_handleCount) { 777 if (!m_handleCount) {
873 if (deleteIfPossible()) 778 if (deleteIfPossible())
874 return; 779 return;
875 unlock(); 780 unlock();
876 } else if (m_handleCount == 1 && memoryCache()->contains(this)) { 781 } else if (m_handleCount == 1 && memoryCache()->contains(this)) {
877 unlock(); 782 unlock();
878 if (!hasClients()) 783 if (!hasClients())
879 memoryCache()->prune(this); 784 memoryCache()->prune(this);
880 } 785 }
881 } 786 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1090 return "ImportResource"; 995 return "ImportResource";
1091 case Resource::Media: 996 case Resource::Media:
1092 return "Media"; 997 return "Media";
1093 } 998 }
1094 ASSERT_NOT_REACHED(); 999 ASSERT_NOT_REACHED();
1095 return "Unknown"; 1000 return "Unknown";
1096 } 1001 }
1097 #endif // !LOG_DISABLED 1002 #endif // !LOG_DISABLED
1098 1003
1099 } // namespace blink 1004 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/fetch/Resource.h ('k') | Source/core/fetch/ResourceFetcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698