Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 10 matching lines...) Expand all Loading... | |
| 21 Boston, MA 02110-1301, USA. | 21 Boston, MA 02110-1301, USA. |
| 22 */ | 22 */ |
| 23 | 23 |
| 24 #include "core/fetch/Resource.h" | 24 #include "core/fetch/Resource.h" |
| 25 | 25 |
| 26 #include "core/fetch/CachedMetadata.h" | 26 #include "core/fetch/CachedMetadata.h" |
| 27 #include "core/fetch/CrossOriginAccessControl.h" | 27 #include "core/fetch/CrossOriginAccessControl.h" |
| 28 #include "core/fetch/FetchInitiatorTypeNames.h" | 28 #include "core/fetch/FetchInitiatorTypeNames.h" |
| 29 #include "core/fetch/MemoryCache.h" | 29 #include "core/fetch/MemoryCache.h" |
| 30 #include "core/fetch/ResourceClient.h" | 30 #include "core/fetch/ResourceClient.h" |
| 31 #include "core/fetch/ResourceClientOrObserverWalker.h" | 31 #include "core/fetch/ResourceClientWalker.h" |
| 32 #include "core/fetch/ResourceLoader.h" | 32 #include "core/fetch/ResourceLoader.h" |
| 33 #include "core/inspector/InstanceCounters.h" | 33 #include "core/inspector/InstanceCounters.h" |
| 34 #include "platform/Histogram.h" | 34 #include "platform/Histogram.h" |
| 35 #include "platform/RuntimeEnabledFeatures.h" | 35 #include "platform/RuntimeEnabledFeatures.h" |
| 36 #include "platform/SharedBuffer.h" | 36 #include "platform/SharedBuffer.h" |
| 37 #include "platform/TraceEvent.h" | 37 #include "platform/TraceEvent.h" |
| 38 #include "platform/network/HTTPParsers.h" | 38 #include "platform/network/HTTPParsers.h" |
| 39 #include "platform/weborigin/KURL.h" | 39 #include "platform/weborigin/KURL.h" |
| 40 #include "public/platform/Platform.h" | 40 #include "public/platform/Platform.h" |
| 41 #include "public/platform/WebCachePolicy.h" | 41 #include "public/platform/WebCachePolicy.h" |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 301 , m_overheadSize(calculateOverheadSize()) | 301 , m_overheadSize(calculateOverheadSize()) |
| 302 , m_preloadCount(0) | 302 , m_preloadCount(0) |
| 303 , m_preloadDiscoveryTime(0.0) | 303 , m_preloadDiscoveryTime(0.0) |
| 304 , m_cacheIdentifier(MemoryCache::defaultCacheIdentifier()) | 304 , m_cacheIdentifier(MemoryCache::defaultCacheIdentifier()) |
| 305 , m_preloadResult(PreloadNotReferenced) | 305 , m_preloadResult(PreloadNotReferenced) |
| 306 , m_type(type) | 306 , m_type(type) |
| 307 , m_status(NotStarted) | 307 , m_status(NotStarted) |
| 308 , m_needsSynchronousCacheHit(false) | 308 , m_needsSynchronousCacheHit(false) |
| 309 , m_linkPreload(false) | 309 , m_linkPreload(false) |
| 310 , m_isRevalidating(false) | 310 , m_isRevalidating(false) |
| 311 , m_isAlive(false) | |
| 311 , m_options(options) | 312 , m_options(options) |
| 312 , m_responseTimestamp(currentTime()) | 313 , m_responseTimestamp(currentTime()) |
| 313 , m_cancelTimer(this, &Resource::cancelTimerFired) | 314 , m_cancelTimer(this, &Resource::cancelTimerFired) |
| 314 , m_resourceRequest(request) | 315 , m_resourceRequest(request) |
| 315 { | 316 { |
| 316 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car eless updates of the enum. | 317 ASSERT(m_type == unsigned(type)); // m_type is a bitfield, so this tests car eless updates of the enum. |
| 317 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); | 318 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); |
| 318 | 319 |
| 319 // Currently we support the metadata caching only for HTTP family. | 320 // Currently we support the metadata caching only for HTTP family. |
| 320 if (m_resourceRequest.url().protocolIsInHTTPFamily()) | 321 if (m_resourceRequest.url().protocolIsInHTTPFamily()) |
| 321 m_cacheHandler = CachedMetadataHandlerImpl::create(this); | 322 m_cacheHandler = CachedMetadataHandlerImpl::create(this); |
| 322 } | 323 } |
| 323 | 324 |
| 324 Resource::~Resource() | 325 Resource::~Resource() |
| 325 { | 326 { |
| 326 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); | 327 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); |
| 327 } | 328 } |
| 328 | 329 |
| 329 DEFINE_TRACE(Resource) | 330 DEFINE_TRACE(Resource) |
| 330 { | 331 { |
| 331 visitor->trace(m_loader); | 332 visitor->trace(m_loader); |
| 332 visitor->trace(m_cacheHandler); | 333 visitor->trace(m_cacheHandler); |
| 334 visitor->trace(m_clients); | |
| 335 visitor->trace(m_clientsAwaitingCallback); | |
| 336 visitor->trace(m_finishedClients); | |
| 333 } | 337 } |
| 334 | 338 |
| 335 void Resource::setLoader(ResourceLoader* loader) | 339 void Resource::setLoader(ResourceLoader* loader) |
| 336 { | 340 { |
| 337 RELEASE_ASSERT(!m_loader); | 341 RELEASE_ASSERT(!m_loader); |
| 338 ASSERT(stillNeedsLoad()); | 342 ASSERT(stillNeedsLoad()); |
| 339 m_loader = loader; | 343 m_loader = loader; |
| 340 m_status = Pending; | 344 m_status = Pending; |
| 341 } | 345 } |
| 342 | 346 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 | 379 |
| 376 void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) | 380 void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy) |
| 377 { | 381 { |
| 378 m_options.dataBufferingPolicy = dataBufferingPolicy; | 382 m_options.dataBufferingPolicy = dataBufferingPolicy; |
| 379 m_data.clear(); | 383 m_data.clear(); |
| 380 setEncodedSize(0); | 384 setEncodedSize(0); |
| 381 } | 385 } |
| 382 | 386 |
| 383 void Resource::markClientsAndObserversFinished() | 387 void Resource::markClientsAndObserversFinished() |
| 384 { | 388 { |
| 385 HashCountedSet<ResourceClient*> clients; | 389 HeapHashCountedSet<WeakMember<ResourceClient>> clients; |
| 386 m_clients.swap(clients); | 390 m_clients.swap(clients); |
| 387 for (const auto& it : clients) | 391 for (const auto& it : clients) |
| 388 m_finishedClients.add(it.key, it.value); | 392 m_finishedClients.add(it.key, it.value); |
| 389 } | 393 } |
| 390 | 394 |
| 391 void Resource::error(const ResourceError& error) | 395 void Resource::error(const ResourceError& error) |
| 392 { | 396 { |
| 393 ASSERT(!error.isNull()); | 397 ASSERT(!error.isNull()); |
| 394 m_error = error; | 398 m_error = error; |
| 395 m_isRevalidating = false; | 399 m_isRevalidating = false; |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 684 m_preloadResult = PreloadReferencedWhileLoading; | 688 m_preloadResult = PreloadReferencedWhileLoading; |
| 685 else | 689 else |
| 686 m_preloadResult = PreloadReferenced; | 690 m_preloadResult = PreloadReferenced; |
| 687 | 691 |
| 688 if (m_preloadDiscoveryTime) { | 692 if (m_preloadDiscoveryTime) { |
| 689 int timeSinceDiscovery = static_cast<int>(1000 * (monotonicallyIncre asingTime() - m_preloadDiscoveryTime)); | 693 int timeSinceDiscovery = static_cast<int>(1000 * (monotonicallyIncre asingTime() - m_preloadDiscoveryTime)); |
| 690 DEFINE_STATIC_LOCAL(CustomCountHistogram, preloadDiscoveryHistogram, ("PreloadScanner.ReferenceTime", 0, 10000, 50)); | 694 DEFINE_STATIC_LOCAL(CustomCountHistogram, preloadDiscoveryHistogram, ("PreloadScanner.ReferenceTime", 0, 10000, 50)); |
| 691 preloadDiscoveryHistogram.count(timeSinceDiscovery); | 695 preloadDiscoveryHistogram.count(timeSinceDiscovery); |
| 692 } | 696 } |
| 693 } | 697 } |
| 694 if (!hasClientsOrObservers()) | 698 if (!hasClientsOrObservers()) { |
| 699 m_isAlive = true; | |
| 695 memoryCache()->makeLive(this); | 700 memoryCache()->makeLive(this); |
| 701 } | |
| 696 } | 702 } |
| 697 | 703 |
| 698 void Resource::addClient(ResourceClient* client) | 704 void Resource::addClient(ResourceClient* client) |
| 699 { | 705 { |
| 700 willAddClientOrObserver(); | 706 willAddClientOrObserver(); |
| 701 | 707 |
| 702 if (m_isRevalidating) { | 708 if (m_isRevalidating) { |
| 703 m_clients.add(client); | 709 m_clients.add(client); |
| 704 return; | 710 return; |
| 705 } | 711 } |
| 706 | 712 |
| 707 // If we have existing data to send to the new client and the resource type supprts it, send it asynchronously. | 713 // If we have existing data to send to the new client and the resource type supprts it, send it asynchronously. |
| 708 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(getTyp e()) && !m_needsSynchronousCacheHit) { | 714 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(getTyp e()) && !m_needsSynchronousCacheHit) { |
| 709 m_clientsAwaitingCallback.add(client); | 715 m_clientsAwaitingCallback.add(client); |
| 710 ResourceCallback::callbackHandler().schedule(this); | 716 ResourceCallback::callbackHandler().schedule(this); |
| 711 return; | 717 return; |
| 712 } | 718 } |
| 713 | 719 |
| 714 m_clients.add(client); | 720 m_clients.add(client); |
| 715 didAddClient(client); | 721 didAddClient(client); |
| 716 return; | 722 return; |
| 717 } | 723 } |
| 718 | 724 |
| 719 void Resource::removeClient(ResourceClient* client) | 725 void Resource::removeClient(ResourceClient* client) |
| 720 { | 726 { |
| 721 ASSERT(hasClient(client)); | 727 if (!hasClient(client)) { |
|
haraken
2016/08/18 08:06:17
I begin to think this is problematic...
If Resour
yhirano
2016/08/18 08:31:53
Hmm, I did think the weak processing is executed i
yhirano
2016/08/18 08:53:15
What problems do we have in such a case? I think L
haraken
2016/08/18 09:11:01
Does it mean that it's always safe to run line 734
yhirano
2016/08/26 09:12:16
Even without this change removeClient can be calle
haraken
2016/08/26 09:49:29
My question is: Why do we need to have the branch
yhirano
2016/08/26 10:08:55
Because it's possible that a Resource is reachable
haraken
2016/08/26 10:19:51
It will happen, but what's a problem of running li
yhirano
2016/08/26 10:26:12
Hm, I didn't think of that. It looks safe as HashC
| |
| 728 // This code may be called in a pre-finalizer, where weak members in the | |
| 729 // HashCountedSet are already swept out. In that case, we just need to | |
| 730 // call didRemoveClientOrObserver(). | |
| 731 didRemoveClientOrObserver(); | |
| 732 return; | |
| 733 } | |
| 722 if (m_finishedClients.contains(client)) | 734 if (m_finishedClients.contains(client)) |
| 723 m_finishedClients.remove(client); | 735 m_finishedClients.remove(client); |
| 724 else if (m_clientsAwaitingCallback.contains(client)) | 736 else if (m_clientsAwaitingCallback.contains(client)) |
| 725 m_clientsAwaitingCallback.remove(client); | 737 m_clientsAwaitingCallback.remove(client); |
| 726 else | 738 else |
| 727 m_clients.remove(client); | 739 m_clients.remove(client); |
| 728 | 740 |
| 729 if (m_clientsAwaitingCallback.isEmpty()) | 741 if (m_clientsAwaitingCallback.isEmpty()) |
| 730 ResourceCallback::callbackHandler().cancel(this); | 742 ResourceCallback::callbackHandler().cancel(this); |
| 731 | 743 |
| 732 didRemoveClientOrObserver(); | 744 didRemoveClientOrObserver(); |
| 733 // This object may be dead here. | |
| 734 } | 745 } |
| 735 | 746 |
| 736 void Resource::didRemoveClientOrObserver() | 747 void Resource::didRemoveClientOrObserver() |
| 737 { | 748 { |
| 738 if (!hasClientsOrObservers()) { | 749 if (!hasClientsOrObservers() && m_isAlive) { |
| 750 m_isAlive = false; | |
| 739 memoryCache()->makeDead(this); | 751 memoryCache()->makeDead(this); |
| 740 allClientsAndObserversRemoved(); | 752 allClientsAndObserversRemoved(); |
| 741 | 753 |
| 742 // RFC2616 14.9.2: | 754 // RFC2616 14.9.2: |
| 743 // "no-store: ... MUST make a best-effort attempt to remove the informat ion from volatile storage as promptly as possible" | 755 // "no-store: ... MUST make a best-effort attempt to remove the informat ion from volatile storage as promptly as possible" |
| 744 // "... History buffers MAY store such responses as part of their normal operation." | 756 // "... History buffers MAY store such responses as part of their normal operation." |
| 745 // We allow non-secure content to be reused in history, but we do not al low secure content to be reused. | 757 // We allow non-secure content to be reused in history, but we do not al low secure content to be reused. |
| 746 if (hasCacheControlNoStoreHeader() && url().protocolIs("https")) { | 758 if (hasCacheControlNoStoreHeader() && url().protocolIs("https")) { |
| 747 memoryCache()->remove(this); | 759 memoryCache()->remove(this); |
| 748 memoryCache()->prune(); | 760 memoryCache()->prune(); |
| 749 } else { | 761 } else { |
| 750 memoryCache()->prune(this); | 762 memoryCache()->prune(this); |
| 751 } | 763 } |
| 752 } | 764 } |
| 753 // This object may be dead here. | 765 // This object may be dead here. |
|
haraken
2016/08/18 09:11:01
I think we can now remove this comment because Res
yhirano
2016/08/26 09:12:16
Yes, there are many stale comments but I don't wan
| |
| 754 } | 766 } |
| 755 | 767 |
| 756 void Resource::allClientsAndObserversRemoved() | 768 void Resource::allClientsAndObserversRemoved() |
| 757 { | 769 { |
| 758 if (!m_loader) | 770 if (!m_loader) |
| 759 return; | 771 return; |
| 760 if (m_type == Raw) | 772 if (m_type == Raw) |
| 761 cancelTimerFired(&m_cancelTimer); | 773 cancelTimerFired(&m_cancelTimer); |
| 762 else if (!m_cancelTimer.isActive()) | 774 else if (!m_cancelTimer.isActive()) |
| 763 m_cancelTimer.startOneShot(0, BLINK_FROM_HERE); | 775 m_cancelTimer.startOneShot(0, BLINK_FROM_HERE); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 801 { | 813 { |
| 802 // We're going to notify clients one by one. It is simple if the client does nothing. | 814 // We're going to notify clients one by one. It is simple if the client does nothing. |
| 803 // However there are a couple other things that can happen. | 815 // However there are a couple other things that can happen. |
| 804 // | 816 // |
| 805 // 1. Clients can be added during the loop. Make sure they are not processed . | 817 // 1. Clients can be added during the loop. Make sure they are not processed . |
| 806 // 2. Clients can be removed during the loop. Make sure they are always avai lable to be | 818 // 2. Clients can be removed during the loop. Make sure they are always avai lable to be |
| 807 // removed. Also don't call removed clients or add them back. | 819 // removed. Also don't call removed clients or add them back. |
| 808 | 820 |
| 809 // Handle case (1) by saving a list of clients to notify. A separate list al so ensure | 821 // Handle case (1) by saving a list of clients to notify. A separate list al so ensure |
| 810 // a client is either in m_clients or m_clientsAwaitingCallback. | 822 // a client is either in m_clients or m_clientsAwaitingCallback. |
| 811 Vector<ResourceClient*> clientsToNotify; | 823 HeapVector<Member<ResourceClient>> clientsToNotify; |
| 812 copyToVector(m_clientsAwaitingCallback, clientsToNotify); | 824 copyToVector(m_clientsAwaitingCallback, clientsToNotify); |
| 813 | 825 |
| 814 for (const auto& client : clientsToNotify) { | 826 for (const auto& client : clientsToNotify) { |
| 815 // Handle case (2) to skip removed clients. | 827 // Handle case (2) to skip removed clients. |
| 816 if (!m_clientsAwaitingCallback.remove(client)) | 828 if (!m_clientsAwaitingCallback.remove(client)) |
| 817 continue; | 829 continue; |
| 818 m_clients.add(client); | 830 m_clients.add(client); |
| 819 didAddClient(client); | 831 didAddClient(client); |
| 820 } | 832 } |
| 821 | 833 |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1111 case Resource::TextTrack: | 1123 case Resource::TextTrack: |
| 1112 case Resource::Media: | 1124 case Resource::Media: |
| 1113 case Resource::Manifest: | 1125 case Resource::Manifest: |
| 1114 return false; | 1126 return false; |
| 1115 } | 1127 } |
| 1116 ASSERT_NOT_REACHED(); | 1128 ASSERT_NOT_REACHED(); |
| 1117 return false; | 1129 return false; |
| 1118 } | 1130 } |
| 1119 | 1131 |
| 1120 } // namespace blink | 1132 } // namespace blink |
| OLD | NEW |