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

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

Issue 1410313002: Revert of Revalidate using the same Resource, attempt #3 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 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
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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 , m_requestedFromNetworkingLayer(false) 158 , m_requestedFromNetworkingLayer(false)
159 , m_loading(false) 159 , m_loading(false)
160 , m_switchingClientsToRevalidatedResource(false) 160 , m_switchingClientsToRevalidatedResource(false)
161 , m_type(type) 161 , m_type(type)
162 , m_status(Pending) 162 , m_status(Pending)
163 , m_wasPurged(false) 163 , m_wasPurged(false)
164 , m_needsSynchronousCacheHit(false) 164 , m_needsSynchronousCacheHit(false)
165 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK 165 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
166 , m_deleted(false) 166 , m_deleted(false)
167 #endif 167 #endif
168 , m_resourceToRevalidate(nullptr)
169 , m_proxyResource(nullptr)
168 { 170 {
169 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car eless updates of the enum. 171 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car eless updates of the enum.
170 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); 172 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter);
171 memoryCache()->registerLiveResource(*this); 173 memoryCache()->registerLiveResource(*this);
172 174
173 // Currently we support the metadata caching only for HTTP family. 175 // Currently we support the metadata caching only for HTTP family.
174 if (m_resourceRequest.url().protocolIsInHTTPFamily()) 176 if (m_resourceRequest.url().protocolIsInHTTPFamily())
175 m_cacheHandler = CacheHandler::create(this); 177 m_cacheHandler = CacheHandler::create(this);
176 178
177 if (!m_resourceRequest.url().hasFragmentIdentifier()) 179 if (!m_resourceRequest.url().hasFragmentIdentifier())
178 return; 180 return;
179 KURL urlForCache = MemoryCache::removeFragmentIdentifierIfNeeded(m_resourceR equest.url()); 181 KURL urlForCache = MemoryCache::removeFragmentIdentifierIfNeeded(m_resourceR equest.url());
180 if (urlForCache.hasFragmentIdentifier()) 182 if (urlForCache.hasFragmentIdentifier())
181 return; 183 return;
182 m_fragmentIdentifierForRequest = m_resourceRequest.url().fragmentIdentifier( ); 184 m_fragmentIdentifierForRequest = m_resourceRequest.url().fragmentIdentifier( );
183 m_resourceRequest.setURL(urlForCache); 185 m_resourceRequest.setURL(urlForCache);
184 } 186 }
185 187
186 Resource::~Resource() 188 Resource::~Resource()
187 { 189 {
190 ASSERT(!m_resourceToRevalidate); // Should be true because canDelete() check s this.
188 ASSERT(canDelete()); 191 ASSERT(canDelete());
189 RELEASE_ASSERT(!memoryCache()->contains(this)); 192 RELEASE_ASSERT(!memoryCache()->contains(this));
190 RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this)); 193 RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this));
191 assertAlive(); 194 assertAlive();
192 195
193 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK 196 #ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
194 m_deleted = true; 197 m_deleted = true;
195 #endif 198 #endif
196 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); 199 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter);
197 } 200 }
198 201
199 void Resource::dispose() 202 void Resource::dispose()
200 { 203 {
201 } 204 }
202 205
203 DEFINE_TRACE(Resource) 206 DEFINE_TRACE(Resource)
204 { 207 {
205 visitor->trace(m_loader); 208 visitor->trace(m_loader);
209 visitor->trace(m_resourceToRevalidate);
210 visitor->trace(m_proxyResource);
206 #if ENABLE(OILPAN) 211 #if ENABLE(OILPAN)
207 visitor->trace(m_cacheHandler); 212 visitor->trace(m_cacheHandler);
208 #endif 213 #endif
209 } 214 }
210 215
211 void Resource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions& optio ns) 216 void Resource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions& optio ns)
212 { 217 {
213 m_options = options; 218 m_options = options;
214 m_loading = true; 219 m_loading = true;
215 220
216 ResourceRequest request(m_revalidatingRequest.isNull() ? m_resourceRequest : m_revalidatingRequest);
217 if (!accept().isEmpty()) 221 if (!accept().isEmpty())
218 request.setHTTPAccept(accept()); 222 m_resourceRequest.setHTTPAccept(accept());
219 223
220 // FIXME: It's unfortunate that the cache layer and below get to know anythi ng about fragment identifiers. 224 // FIXME: It's unfortunate that the cache layer and below get to know anythi ng about fragment identifiers.
221 // We should look into removing the expectation of that knowledge from the p latform network stacks. 225 // We should look into removing the expectation of that knowledge from the p latform network stacks.
226 ResourceRequest request(m_resourceRequest);
222 if (!m_fragmentIdentifierForRequest.isNull()) { 227 if (!m_fragmentIdentifierForRequest.isNull()) {
223 KURL url = request.url(); 228 KURL url = request.url();
224 url.setFragmentIdentifier(m_fragmentIdentifierForRequest); 229 url.setFragmentIdentifier(m_fragmentIdentifierForRequest);
225 request.setURL(url); 230 request.setURL(url);
226 m_fragmentIdentifierForRequest = String(); 231 m_fragmentIdentifierForRequest = String();
227 } 232 }
228 m_status = Pending; 233 m_status = Pending;
229 if (m_loader) { 234 if (m_loader) {
230 ASSERT(m_revalidatingRequest.isNull());
231 RELEASE_ASSERT(m_options.synchronousPolicy == RequestSynchronously); 235 RELEASE_ASSERT(m_options.synchronousPolicy == RequestSynchronously);
232 m_loader->changeToSynchronous(); 236 m_loader->changeToSynchronous();
233 return; 237 return;
234 } 238 }
235 m_loader = ResourceLoader::create(fetcher, this, request, options); 239 m_loader = ResourceLoader::create(fetcher, this, request, options);
236 m_loader->start(); 240 m_loader->start();
237 } 241 }
238 242
239 void Resource::checkNotify() 243 void Resource::checkNotify()
240 { 244 {
241 if (isLoading()) 245 if (isLoading())
242 return; 246 return;
243 247
244 ResourceClientWalker<ResourceClient> w(m_clients); 248 ResourceClientWalker<ResourceClient> w(m_clients);
245 while (ResourceClient* c = w.next()) 249 while (ResourceClient* c = w.next())
246 c->notifyFinished(this); 250 c->notifyFinished(this);
247 } 251 }
248 252
249 void Resource::appendData(const char* data, unsigned length) 253 void Resource::appendData(const char* data, unsigned length)
250 { 254 {
251 TRACE_EVENT0("blink", "Resource::appendData"); 255 TRACE_EVENT0("blink", "Resource::appendData");
252 ASSERT(m_revalidatingRequest.isNull()); 256 ASSERT(!m_resourceToRevalidate);
253 ASSERT(!errorOccurred()); 257 ASSERT(!errorOccurred());
254 if (m_options.dataBufferingPolicy == DoNotBufferData) 258 if (m_options.dataBufferingPolicy == DoNotBufferData)
255 return; 259 return;
256 if (m_data) 260 if (m_data)
257 m_data->append(data, length); 261 m_data->append(data, length);
258 else 262 else
259 m_data = SharedBuffer::createPurgeable(data, length); 263 m_data = SharedBuffer::createPurgeable(data, length);
260 setEncodedSize(m_data->size()); 264 setEncodedSize(m_data->size());
261 } 265 }
262 266
263 void Resource::setResourceBuffer(PassRefPtr<SharedBuffer> resourceBuffer) 267 void Resource::setResourceBuffer(PassRefPtr<SharedBuffer> resourceBuffer)
264 { 268 {
265 ASSERT(m_revalidatingRequest.isNull()); 269 ASSERT(!m_resourceToRevalidate);
266 ASSERT(!errorOccurred()); 270 ASSERT(!errorOccurred());
267 ASSERT(m_options.dataBufferingPolicy == BufferData); 271 ASSERT(m_options.dataBufferingPolicy == BufferData);
268 m_data = resourceBuffer; 272 m_data = resourceBuffer;
269 setEncodedSize(m_data->size()); 273 setEncodedSize(m_data->size());
270 } 274 }
271 275
272 void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) 276 void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy)
273 { 277 {
274 m_options.dataBufferingPolicy = dataBufferingPolicy; 278 m_options.dataBufferingPolicy = dataBufferingPolicy;
275 m_data.clear(); 279 m_data.clear();
276 setEncodedSize(0); 280 setEncodedSize(0);
277 } 281 }
278 282
279 void Resource::markClientsFinished()
280 {
281 while (!m_clients.isEmpty()) {
282 HashCountedSet<ResourceClient*>::iterator it = m_clients.begin();
283 for (int i = it->value; i; i--) {
284 m_finishedClients.add(it->key);
285 m_clients.remove(it);
286 }
287 }
288 }
289
290 void Resource::error(Resource::Status status) 283 void Resource::error(Resource::Status status)
291 { 284 {
292 if (!m_revalidatingRequest.isNull()) 285 if (m_resourceToRevalidate)
293 m_revalidatingRequest = ResourceRequest(); 286 revalidationFailed();
294 287
295 if (!m_error.isNull() && (m_error.isCancellation() || !isPreloaded())) 288 if (!m_error.isNull() && (m_error.isCancellation() || !isPreloaded()))
296 memoryCache()->remove(this); 289 memoryCache()->remove(this);
297 290
298 setStatus(status); 291 setStatus(status);
299 ASSERT(errorOccurred()); 292 ASSERT(errorOccurred());
300 m_data.clear(); 293 m_data.clear();
301 294
302 setLoading(false); 295 setLoading(false);
303 checkNotify(); 296 checkNotify();
304 markClientsFinished();
305 } 297 }
306 298
307 void Resource::finishOnePart() 299 void Resource::finishOnePart()
308 { 300 {
309 setLoading(false); 301 setLoading(false);
310 checkNotify(); 302 checkNotify();
311 } 303 }
312 304
313 void Resource::finish() 305 void Resource::finish()
314 { 306 {
315 ASSERT(m_revalidatingRequest.isNull()); 307 ASSERT(!m_resourceToRevalidate);
316 ASSERT(!errorOccurred()); 308 ASSERT(!errorOccurred());
317 finishOnePart(); 309 finishOnePart();
318 markClientsFinished();
319 if (!errorOccurred()) 310 if (!errorOccurred())
320 m_status = Cached; 311 m_status = Cached;
321 } 312 }
322 313
323 bool Resource::passesAccessControlCheck(SecurityOrigin* securityOrigin) const 314 bool Resource::passesAccessControlCheck(SecurityOrigin* securityOrigin) const
324 { 315 {
325 String ignoredErrorDescription; 316 String ignoredErrorDescription;
326 return passesAccessControlCheck(securityOrigin, ignoredErrorDescription); 317 return passesAccessControlCheck(securityOrigin, ignoredErrorDescription);
327 } 318 }
328 319
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 } 424 }
434 425
435 bool Resource::unlock() 426 bool Resource::unlock()
436 { 427 {
437 if (!m_data) 428 if (!m_data)
438 return false; 429 return false;
439 430
440 if (!m_data->isLocked()) 431 if (!m_data->isLocked())
441 return true; 432 return true;
442 433
443 if (!memoryCache()->contains(this) || hasClients() || m_handleCount > 1 || ! m_revalidatingRequest.isNull() || !m_loadFinishTime || !isSafeToUnlock()) 434 if (!memoryCache()->contains(this) || hasClients() || m_handleCount > 1 || m _proxyResource || m_resourceToRevalidate || !m_loadFinishTime || !isSafeToUnlock ())
444 return false; 435 return false;
445 436
446 m_data->unlock(); 437 m_data->unlock();
447 return true; 438 return true;
448 } 439 }
449 440
450 bool Resource::hasRightHandleCountApartFromCache(unsigned targetCount) const 441 bool Resource::hasRightHandleCountApartFromCache(unsigned targetCount) const
451 { 442 {
452 return m_handleCount == targetCount + (memoryCache()->contains(this) ? 1 : 0 ); 443 return m_handleCount == targetCount + (memoryCache()->contains(this) ? 1 : 0 );
453 } 444 }
454 445
455 void Resource::responseReceived(const ResourceResponse& response, PassOwnPtr<Web DataConsumerHandle>) 446 void Resource::responseReceived(const ResourceResponse& response, PassOwnPtr<Web DataConsumerHandle>)
456 { 447 {
448 setResponse(response);
457 m_responseTimestamp = currentTime(); 449 m_responseTimestamp = currentTime();
458
459 if (!m_revalidatingRequest.isNull()) {
460 if (response.httpStatusCode() == 304) {
461 revalidationSucceeded(response);
462 return;
463 }
464 revalidationFailed();
465 }
466
467 setResponse(response);
468 String encoding = response.textEncodingName(); 450 String encoding = response.textEncodingName();
469 if (!encoding.isNull()) 451 if (!encoding.isNull())
470 setEncoding(encoding); 452 setEncoding(encoding);
453
454 if (!m_resourceToRevalidate)
455 return;
456 if (response.httpStatusCode() == 304)
457 revalidationSucceeded(response);
458 else
459 revalidationFailed();
471 } 460 }
472 461
473 void Resource::setSerializedCachedMetadata(const char* data, size_t size) 462 void Resource::setSerializedCachedMetadata(const char* data, size_t size)
474 { 463 {
475 // We only expect to receive cached metadata from the platform once. 464 // We only expect to receive cached metadata from the platform once.
476 // If this triggers, it indicates an efficiency problem which is most 465 // If this triggers, it indicates an efficiency problem which is most
477 // likely unexpected in code designed to improve performance. 466 // likely unexpected in code designed to improve performance.
478 ASSERT(!m_cachedMetadata); 467 ASSERT(!m_cachedMetadata);
479 ASSERT(m_revalidatingRequest.isNull()); 468 ASSERT(!m_resourceToRevalidate);
480 469
481 m_cachedMetadata = CachedMetadata::deserialize(data, size); 470 m_cachedMetadata = CachedMetadata::deserialize(data, size);
482 } 471 }
483 472
484 CachedMetadataHandler* Resource::cacheHandler() 473 CachedMetadataHandler* Resource::cacheHandler()
485 { 474 {
486 return m_cacheHandler.get(); 475 return m_cacheHandler.get();
487 } 476 }
488 477
489 void Resource::setCachedMetadata(unsigned dataTypeID, const char* data, size_t s ize, CachedMetadataHandler::CacheType cacheType) 478 void Resource::setCachedMetadata(unsigned dataTypeID, const char* data, size_t s ize, CachedMetadataHandler::CacheType cacheType)
(...skipping 20 matching lines...) Expand all
510 { 499 {
511 m_cachedMetadata.clear(); 500 m_cachedMetadata.clear();
512 501
513 if (cacheType == CachedMetadataHandler::SendToPlatform) 502 if (cacheType == CachedMetadataHandler::SendToPlatform)
514 Platform::current()->cacheMetadata(m_response.url(), m_response.response Time(), 0, 0); 503 Platform::current()->cacheMetadata(m_response.url(), m_response.response Time(), 0, 0);
515 } 504 }
516 505
517 bool Resource::canDelete() const 506 bool Resource::canDelete() const
518 { 507 {
519 return !hasClients() && !m_loader && !m_preloadCount && hasRightHandleCountA partFromCache(0) 508 return !hasClients() && !m_loader && !m_preloadCount && hasRightHandleCountA partFromCache(0)
520 && !m_protectorCount; 509 && !m_protectorCount && !m_resourceToRevalidate && !m_proxyResource;
521 } 510 }
522 511
523 bool Resource::hasOneHandle() const 512 bool Resource::hasOneHandle() const
524 { 513 {
525 return hasRightHandleCountApartFromCache(1); 514 return hasRightHandleCountApartFromCache(1);
526 } 515 }
527 516
528 CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const 517 CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const
529 { 518 {
530 if (!m_cachedMetadata || m_cachedMetadata->dataTypeID() != dataTypeID) 519 if (!m_cachedMetadata || m_cachedMetadata->dataTypeID() != dataTypeID)
531 return nullptr; 520 return nullptr;
532 return m_cachedMetadata.get(); 521 return m_cachedMetadata.get();
533 } 522 }
534 523
535 void Resource::clearLoader() 524 void Resource::clearLoader()
536 { 525 {
537 m_loader = nullptr; 526 m_loader = nullptr;
538 } 527 }
539 528
529 void Resource::addClient(ResourceClient* client)
530 {
531 if (addClientToSet(client))
532 didAddClient(client);
533 }
534
540 void Resource::didAddClient(ResourceClient* c) 535 void Resource::didAddClient(ResourceClient* c)
541 { 536 {
542 if (!isLoading() && !stillNeedsLoad()) { 537 if (!isLoading() && !stillNeedsLoad())
543 c->notifyFinished(this); 538 c->notifyFinished(this);
544 if (m_clients.contains(c)) {
545 m_finishedClients.add(c);
546 m_clients.remove(c);
547 }
548 }
549 } 539 }
550 540
551 static bool shouldSendCachedDataSynchronouslyForType(Resource::Type type) 541 static bool shouldSendCachedDataSynchronouslyForType(Resource::Type type)
552 { 542 {
553 // Some resources types default to return data synchronously. 543 // Some resources types default to return data synchronously.
554 // For most of these, it's because there are layout tests that 544 // For most of these, it's because there are layout tests that
555 // expect data to return synchronously in case of cache hit. In 545 // expect data to return synchronously in case of cache hit. In
556 // the case of fonts, there was a performance regression. 546 // the case of fonts, there was a performance regression.
557 // FIXME: Get to the point where we don't need to special-case sync/async 547 // FIXME: Get to the point where we don't need to special-case sync/async
558 // behavior for different resource types. 548 // behavior for different resource types.
559 if (type == Resource::Image) 549 if (type == Resource::Image)
560 return true; 550 return true;
561 if (type == Resource::CSSStyleSheet) 551 if (type == Resource::CSSStyleSheet)
562 return true; 552 return true;
563 if (type == Resource::Script) 553 if (type == Resource::Script)
564 return true; 554 return true;
565 if (type == Resource::Font) 555 if (type == Resource::Font)
566 return true; 556 return true;
567 return false; 557 return false;
568 } 558 }
569 559
570 void Resource::addClient(ResourceClient* client) 560 bool Resource::addClientToSet(ResourceClient* client)
571 { 561 {
572 ASSERT(!isPurgeable()); 562 ASSERT(!isPurgeable());
573 563
574 if (m_preloadResult == PreloadNotReferenced) { 564 if (m_preloadResult == PreloadNotReferenced) {
575 if (isLoaded()) 565 if (isLoaded())
576 m_preloadResult = PreloadReferencedWhileComplete; 566 m_preloadResult = PreloadReferencedWhileComplete;
577 else if (m_requestedFromNetworkingLayer) 567 else if (m_requestedFromNetworkingLayer)
578 m_preloadResult = PreloadReferencedWhileLoading; 568 m_preloadResult = PreloadReferencedWhileLoading;
579 else 569 else
580 m_preloadResult = PreloadReferenced; 570 m_preloadResult = PreloadReferenced;
581 } 571 }
582 if (!hasClients()) 572 if (!hasClients())
583 memoryCache()->makeLive(this); 573 memoryCache()->makeLive(this);
584 574
585 if (!m_revalidatingRequest.isNull()) {
586 m_clients.add(client);
587 return;
588 }
589
590 // If we have existing data to send to the new client and the resource type supprts it, send it asynchronously. 575 // If we have existing data to send to the new client and the resource type supprts it, send it asynchronously.
591 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(type() ) && !m_needsSynchronousCacheHit) { 576 if (!m_response.isNull() && !m_proxyResource && !shouldSendCachedDataSynchro nouslyForType(type()) && !m_needsSynchronousCacheHit) {
592 m_clientsAwaitingCallback.add(client); 577 m_clientsAwaitingCallback.add(client);
593 ResourceCallback::callbackHandler()->schedule(this); 578 ResourceCallback::callbackHandler()->schedule(this);
594 return; 579 return false;
595 } 580 }
596 581
597 m_clients.add(client); 582 m_clients.add(client);
598 didAddClient(client); 583 return true;
599 return;
600 } 584 }
601 585
602 void Resource::removeClient(ResourceClient* client) 586 void Resource::removeClient(ResourceClient* client)
603 { 587 {
604 ASSERT(hasClient(client)); 588 if (m_clientsAwaitingCallback.contains(client)) {
605 if (m_finishedClients.contains(client)) 589 ASSERT(!m_clients.contains(client));
606 m_finishedClients.remove(client);
607 else if (m_clientsAwaitingCallback.contains(client))
608 m_clientsAwaitingCallback.remove(client); 590 m_clientsAwaitingCallback.remove(client);
609 else 591 } else {
592 ASSERT(m_clients.contains(client));
610 m_clients.remove(client); 593 m_clients.remove(client);
611 594 didRemoveClient(client);
612 didRemoveClient(client); 595 }
613 596
614 if (m_clientsAwaitingCallback.isEmpty()) 597 if (m_clientsAwaitingCallback.isEmpty())
615 ResourceCallback::callbackHandler()->cancel(this); 598 ResourceCallback::callbackHandler()->cancel(this);
616 599
617 bool deleted = deleteIfPossible(); 600 bool deleted = deleteIfPossible();
618 if (!deleted && !hasClients()) { 601 if (!deleted && !hasClients()) {
619 memoryCache()->makeDead(this); 602 memoryCache()->makeDead(this);
620 if (!m_switchingClientsToRevalidatedResource) 603 if (!m_switchingClientsToRevalidatedResource)
621 allClientsRemoved(); 604 allClientsRemoved();
622 605
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 // Prevent the case when there are clients waiting but no callback scheduled . 710 // Prevent the case when there are clients waiting but no callback scheduled .
728 ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled); 711 ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled);
729 } 712 }
730 713
731 void Resource::prune() 714 void Resource::prune()
732 { 715 {
733 destroyDecodedDataIfPossible(); 716 destroyDecodedDataIfPossible();
734 unlock(); 717 unlock();
735 } 718 }
736 719
720 void Resource::setResourceToRevalidate(Resource* resource)
721 {
722 ASSERT(resource);
723 ASSERT(!m_resourceToRevalidate);
724 ASSERT(resource != this);
725 ASSERT(m_handlesToRevalidate.isEmpty());
726 ASSERT(resource->type() == type());
737 727
738 void Resource::revalidationSucceeded(const ResourceResponse& validatingResponse) 728 WTF_LOG(ResourceLoading, "Resource %p setResourceToRevalidate %p", this, res ource);
729
730 // The following assert should be investigated whenever it occurs. Although it should never fire, it currently does in rare circumstances.
731 // https://bugs.webkit.org/show_bug.cgi?id=28604.
732 // So the code needs to be robust to this assert failing thus the "if (m_res ourceToRevalidate->m_proxyResource == this)" in Resource::clearResourceToRevalid ate.
733 ASSERT(!resource->m_proxyResource);
734
735 resource->m_proxyResource = this;
736 m_resourceToRevalidate = resource;
737 }
738
739 void Resource::clearResourceToRevalidate()
740 {
741 ASSERT(m_resourceToRevalidate);
742 if (m_switchingClientsToRevalidatedResource)
743 return;
744
745 // 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.
746 if (m_resourceToRevalidate->m_proxyResource == this) {
747 m_resourceToRevalidate->m_proxyResource = nullptr;
748 m_resourceToRevalidate->deleteIfPossible();
749 }
750 m_handlesToRevalidate.clear();
751 m_resourceToRevalidate = nullptr;
752 deleteIfPossible();
753 }
754
755 void Resource::switchClientsToRevalidatedResource()
756 {
757 ASSERT(m_resourceToRevalidate);
758 ASSERT(memoryCache()->contains(m_resourceToRevalidate));
759 ASSERT(!memoryCache()->contains(this));
760
761 WTF_LOG(ResourceLoading, "Resource %p switchClientsToRevalidatedResource %p" , this, m_resourceToRevalidate.get());
762
763 m_resourceToRevalidate->m_identifier = m_identifier;
764
765 m_switchingClientsToRevalidatedResource = true;
766 for (ResourcePtrBase* handle : m_handlesToRevalidate) {
767 handle->m_resource = m_resourceToRevalidate;
768 m_resourceToRevalidate->registerHandle(handle);
769 --m_handleCount;
770 }
771 ASSERT(!m_handleCount);
772 m_handlesToRevalidate.clear();
773
774 Vector<ResourceClient*> clientsToMove;
775 for (const auto& clientHashEntry : m_clients) {
776 unsigned count = clientHashEntry.value;
777 while (count--)
778 clientsToMove.append(clientHashEntry.key);
779 }
780
781 unsigned moveCount = clientsToMove.size();
782 for (unsigned n = 0; n < moveCount; ++n)
783 removeClient(clientsToMove[n]);
784 ASSERT(m_clients.isEmpty());
785
786 for (unsigned n = 0; n < moveCount; ++n)
787 m_resourceToRevalidate->addClientToSet(clientsToMove[n]);
788 for (unsigned n = 0; n < moveCount; ++n) {
789 // Calling didAddClient may do anything, including trying to cancel reva lidation.
790 // Assert that it didn't succeed.
791 ASSERT(m_resourceToRevalidate);
792 // Calling didAddClient for a client may end up removing another client. In that case it won't be in the set anymore.
793 if (m_resourceToRevalidate->m_clients.contains(clientsToMove[n]))
794 m_resourceToRevalidate->didAddClient(clientsToMove[n]);
795 }
796 m_switchingClientsToRevalidatedResource = false;
797 }
798
799 void Resource::updateResponseAfterRevalidation(const ResourceResponse& validatin gResponse)
739 { 800 {
740 m_responseTimestamp = currentTime(); 801 m_responseTimestamp = currentTime();
741 m_response.setResourceLoadTiming(validatingResponse.resourceLoadTiming());
742 802
743 // RFC2616 10.3.5 803 // RFC2616 10.3.5
744 // Update cached headers from the 304 response 804 // Update cached headers from the 304 response
745 const HTTPHeaderMap& newHeaders = validatingResponse.httpHeaderFields(); 805 const HTTPHeaderMap& newHeaders = validatingResponse.httpHeaderFields();
746 for (const auto& header : newHeaders) { 806 for (const auto& header : newHeaders) {
747 // Entity headers should not be sent by servers when generating a 304 807 // Entity headers should not be sent by servers when generating a 304
748 // response; misconfigured servers send them anyway. We shouldn't allow 808 // response; misconfigured servers send them anyway. We shouldn't allow
749 // such headers to update the original request. We'll base this on the 809 // such headers to update the original request. We'll base this on the
750 // list defined by RFC2616 7.1, with a few additions for extension heade rs 810 // list defined by RFC2616 7.1, with a few additions for extension heade rs
751 // we care about. 811 // we care about.
752 if (!shouldUpdateHeaderAfterRevalidation(header.key)) 812 if (!shouldUpdateHeaderAfterRevalidation(header.key))
753 continue; 813 continue;
754 m_response.setHTTPHeaderField(header.key, header.value); 814 m_response.setHTTPHeaderField(header.key, header.value);
755 } 815 }
816 }
756 817
818 void Resource::revalidationSucceeded(const ResourceResponse& response)
819 {
820 ASSERT(m_resourceToRevalidate);
821 ASSERT(!memoryCache()->contains(m_resourceToRevalidate));
822 ASSERT(m_resourceToRevalidate->isLoaded());
823
824 // Calling evict() can potentially delete revalidatingResource, which we use
825 // below. This mustn't be the case since revalidation means it is loaded
826 // and so canDelete() is false.
827 ASSERT(!canDelete());
828
829 m_resourceToRevalidate->updateResponseAfterRevalidation(response);
830 memoryCache()->replace(m_resourceToRevalidate, this);
831
832 switchClientsToRevalidatedResource();
757 assertAlive(); 833 assertAlive();
758 m_resourceRequest = m_revalidatingRequest; 834 // clearResourceToRevalidate deletes this.
759 m_revalidatingRequest = ResourceRequest(); 835 clearResourceToRevalidate();
760 } 836 }
761 837
762 void Resource::revalidationFailed() 838 void Resource::revalidationFailed()
763 { 839 {
764 m_resourceRequest = m_revalidatingRequest; 840 ASSERT(WTF::isMainThread());
765 m_revalidatingRequest = ResourceRequest(); 841 WTF_LOG(ResourceLoading, "Revalidation failed for %p", this);
766 m_data.clear(); 842 ASSERT(resourceToRevalidate());
767 destroyDecodedDataForFailedRevalidation(); 843 clearResourceToRevalidate();
768 } 844 }
769 845
770 void Resource::registerHandle(ResourcePtrBase* h) 846 void Resource::registerHandle(ResourcePtrBase* h)
771 { 847 {
772 assertAlive(); 848 assertAlive();
773 ++m_handleCount; 849 ++m_handleCount;
850 if (m_resourceToRevalidate)
851 m_handlesToRevalidate.add(h);
774 } 852 }
775 853
776 void Resource::unregisterHandle(ResourcePtrBase* h) 854 void Resource::unregisterHandle(ResourcePtrBase* h)
777 { 855 {
778 assertAlive(); 856 assertAlive();
779 ASSERT(m_handleCount > 0); 857 ASSERT(m_handleCount > 0);
780 --m_handleCount; 858 --m_handleCount;
781 859
860 if (m_resourceToRevalidate)
861 m_handlesToRevalidate.remove(h);
862
782 if (!m_handleCount) { 863 if (!m_handleCount) {
783 if (deleteIfPossible()) 864 if (deleteIfPossible())
784 return; 865 return;
785 unlock(); 866 unlock();
786 } else if (m_handleCount == 1 && memoryCache()->contains(this)) { 867 } else if (m_handleCount == 1 && memoryCache()->contains(this)) {
787 unlock(); 868 unlock();
788 if (!hasClients()) 869 if (!hasClients())
789 memoryCache()->prune(this); 870 memoryCache()->prune(this);
790 } 871 }
791 } 872 }
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 return "ImportResource"; 1108 return "ImportResource";
1028 case Resource::Media: 1109 case Resource::Media:
1029 return "Media"; 1110 return "Media";
1030 } 1111 }
1031 ASSERT_NOT_REACHED(); 1112 ASSERT_NOT_REACHED();
1032 return "Unknown"; 1113 return "Unknown";
1033 } 1114 }
1034 #endif // !LOG_DISABLED 1115 #endif // !LOG_DISABLED
1035 1116
1036 } // namespace blink 1117 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/fetch/Resource.h ('k') | third_party/WebKit/Source/core/fetch/ResourceFetcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698