| 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 MemoryCoordinator::instance().registerClient(this); | 323 MemoryCoordinator::instance().registerClient(this); |
| 323 } | 324 } |
| 324 | 325 |
| 325 Resource::~Resource() | 326 Resource::~Resource() |
| 326 { | 327 { |
| 327 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); | 328 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); |
| 328 } | 329 } |
| 329 | 330 |
| 330 DEFINE_TRACE(Resource) | 331 DEFINE_TRACE(Resource) |
| 331 { | 332 { |
| 332 visitor->trace(m_loader); | 333 visitor->trace(m_loader); |
| 333 visitor->trace(m_cacheHandler); | 334 visitor->trace(m_cacheHandler); |
| 335 visitor->trace(m_clients); |
| 336 visitor->trace(m_clientsAwaitingCallback); |
| 337 visitor->trace(m_finishedClients); |
| 334 MemoryCoordinatorClient::trace(visitor); | 338 MemoryCoordinatorClient::trace(visitor); |
| 335 } | 339 } |
| 336 | 340 |
| 337 void Resource::setLoader(ResourceLoader* loader) | 341 void Resource::setLoader(ResourceLoader* loader) |
| 338 { | 342 { |
| 339 RELEASE_ASSERT(!m_loader); | 343 RELEASE_ASSERT(!m_loader); |
| 340 ASSERT(stillNeedsLoad()); | 344 ASSERT(stillNeedsLoad()); |
| 341 m_loader = loader; | 345 m_loader = loader; |
| 342 m_status = Pending; | 346 m_status = Pending; |
| 343 } | 347 } |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 m_preloadResult = PreloadReferencedWhileLoading; | 674 m_preloadResult = PreloadReferencedWhileLoading; |
| 671 else | 675 else |
| 672 m_preloadResult = PreloadReferenced; | 676 m_preloadResult = PreloadReferenced; |
| 673 | 677 |
| 674 if (m_preloadDiscoveryTime) { | 678 if (m_preloadDiscoveryTime) { |
| 675 int timeSinceDiscovery = static_cast<int>(1000 * (monotonicallyIncre
asingTime() - m_preloadDiscoveryTime)); | 679 int timeSinceDiscovery = static_cast<int>(1000 * (monotonicallyIncre
asingTime() - m_preloadDiscoveryTime)); |
| 676 DEFINE_STATIC_LOCAL(CustomCountHistogram, preloadDiscoveryHistogram,
("PreloadScanner.ReferenceTime", 0, 10000, 50)); | 680 DEFINE_STATIC_LOCAL(CustomCountHistogram, preloadDiscoveryHistogram,
("PreloadScanner.ReferenceTime", 0, 10000, 50)); |
| 677 preloadDiscoveryHistogram.count(timeSinceDiscovery); | 681 preloadDiscoveryHistogram.count(timeSinceDiscovery); |
| 678 } | 682 } |
| 679 } | 683 } |
| 680 if (!hasClientsOrObservers()) | 684 if (!hasClientsOrObservers()) { |
| 685 m_isAlive = true; |
| 681 memoryCache()->makeLive(this); | 686 memoryCache()->makeLive(this); |
| 687 } |
| 682 } | 688 } |
| 683 | 689 |
| 684 void Resource::addClient(ResourceClient* client, PreloadReferencePolicy policy) | 690 void Resource::addClient(ResourceClient* client, PreloadReferencePolicy policy) |
| 685 { | 691 { |
| 686 willAddClientOrObserver(policy); | 692 willAddClientOrObserver(policy); |
| 687 | 693 |
| 688 if (m_isRevalidating) { | 694 if (m_isRevalidating) { |
| 689 m_clients.add(client); | 695 m_clients.add(client); |
| 690 return; | 696 return; |
| 691 } | 697 } |
| 692 | 698 |
| 693 // If we have existing data to send to the new client and the resource type
supprts it, send it asynchronously. | 699 // If we have existing data to send to the new client and the resource type
supprts it, send it asynchronously. |
| 694 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(getTyp
e()) && !m_needsSynchronousCacheHit) { | 700 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(getTyp
e()) && !m_needsSynchronousCacheHit) { |
| 695 m_clientsAwaitingCallback.add(client); | 701 m_clientsAwaitingCallback.add(client); |
| 696 ResourceCallback::callbackHandler().schedule(this); | 702 ResourceCallback::callbackHandler().schedule(this); |
| 697 return; | 703 return; |
| 698 } | 704 } |
| 699 | 705 |
| 700 m_clients.add(client); | 706 m_clients.add(client); |
| 701 didAddClient(client); | 707 didAddClient(client); |
| 702 return; | 708 return; |
| 703 } | 709 } |
| 704 | 710 |
| 705 void Resource::removeClient(ResourceClient* client) | 711 void Resource::removeClient(ResourceClient* client) |
| 706 { | 712 { |
| 707 ASSERT(hasClient(client)); | 713 // This code may be called in a pre-finalizer, where weak members in the |
| 714 // HashCountedSet are already swept out. |
| 715 |
| 708 if (m_finishedClients.contains(client)) | 716 if (m_finishedClients.contains(client)) |
| 709 m_finishedClients.remove(client); | 717 m_finishedClients.remove(client); |
| 710 else if (m_clientsAwaitingCallback.contains(client)) | 718 else if (m_clientsAwaitingCallback.contains(client)) |
| 711 m_clientsAwaitingCallback.remove(client); | 719 m_clientsAwaitingCallback.remove(client); |
| 712 else | 720 else |
| 713 m_clients.remove(client); | 721 m_clients.remove(client); |
| 714 | 722 |
| 715 if (m_clientsAwaitingCallback.isEmpty()) | 723 if (m_clientsAwaitingCallback.isEmpty()) |
| 716 ResourceCallback::callbackHandler().cancel(this); | 724 ResourceCallback::callbackHandler().cancel(this); |
| 717 | 725 |
| 718 didRemoveClientOrObserver(); | 726 didRemoveClientOrObserver(); |
| 719 // This object may be dead here. | |
| 720 } | 727 } |
| 721 | 728 |
| 722 void Resource::didRemoveClientOrObserver() | 729 void Resource::didRemoveClientOrObserver() |
| 723 { | 730 { |
| 724 if (!hasClientsOrObservers()) { | 731 if (!hasClientsOrObservers() && m_isAlive) { |
| 732 m_isAlive = false; |
| 725 memoryCache()->makeDead(this); | 733 memoryCache()->makeDead(this); |
| 726 allClientsAndObserversRemoved(); | 734 allClientsAndObserversRemoved(); |
| 727 | 735 |
| 728 // RFC2616 14.9.2: | 736 // RFC2616 14.9.2: |
| 729 // "no-store: ... MUST make a best-effort attempt to remove the informat
ion from volatile storage as promptly as possible" | 737 // "no-store: ... MUST make a best-effort attempt to remove the informat
ion from volatile storage as promptly as possible" |
| 730 // "... History buffers MAY store such responses as part of their normal
operation." | 738 // "... History buffers MAY store such responses as part of their normal
operation." |
| 731 // We allow non-secure content to be reused in history, but we do not al
low secure content to be reused. | 739 // We allow non-secure content to be reused in history, but we do not al
low secure content to be reused. |
| 732 if (hasCacheControlNoStoreHeader() && url().protocolIs("https")) { | 740 if (hasCacheControlNoStoreHeader() && url().protocolIs("https")) { |
| 733 memoryCache()->remove(this); | 741 memoryCache()->remove(this); |
| 734 memoryCache()->prune(); | 742 memoryCache()->prune(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 { | 793 { |
| 786 // We're going to notify clients one by one. It is simple if the client does
nothing. | 794 // We're going to notify clients one by one. It is simple if the client does
nothing. |
| 787 // However there are a couple other things that can happen. | 795 // However there are a couple other things that can happen. |
| 788 // | 796 // |
| 789 // 1. Clients can be added during the loop. Make sure they are not processed
. | 797 // 1. Clients can be added during the loop. Make sure they are not processed
. |
| 790 // 2. Clients can be removed during the loop. Make sure they are always avai
lable to be | 798 // 2. Clients can be removed during the loop. Make sure they are always avai
lable to be |
| 791 // removed. Also don't call removed clients or add them back. | 799 // removed. Also don't call removed clients or add them back. |
| 792 | 800 |
| 793 // Handle case (1) by saving a list of clients to notify. A separate list al
so ensure | 801 // Handle case (1) by saving a list of clients to notify. A separate list al
so ensure |
| 794 // a client is either in m_clients or m_clientsAwaitingCallback. | 802 // a client is either in m_clients or m_clientsAwaitingCallback. |
| 795 Vector<ResourceClient*> clientsToNotify; | 803 HeapVector<Member<ResourceClient>> clientsToNotify; |
| 796 copyToVector(m_clientsAwaitingCallback, clientsToNotify); | 804 copyToVector(m_clientsAwaitingCallback, clientsToNotify); |
| 797 | 805 |
| 798 for (const auto& client : clientsToNotify) { | 806 for (const auto& client : clientsToNotify) { |
| 799 // Handle case (2) to skip removed clients. | 807 // Handle case (2) to skip removed clients. |
| 800 if (!m_clientsAwaitingCallback.remove(client)) | 808 if (!m_clientsAwaitingCallback.remove(client)) |
| 801 continue; | 809 continue; |
| 802 m_clients.add(client); | 810 m_clients.add(client); |
| 803 didAddClient(client); | 811 didAddClient(client); |
| 804 } | 812 } |
| 805 | 813 |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1065 case Resource::TextTrack: | 1073 case Resource::TextTrack: |
| 1066 case Resource::Media: | 1074 case Resource::Media: |
| 1067 case Resource::Manifest: | 1075 case Resource::Manifest: |
| 1068 return false; | 1076 return false; |
| 1069 } | 1077 } |
| 1070 ASSERT_NOT_REACHED(); | 1078 ASSERT_NOT_REACHED(); |
| 1071 return false; | 1079 return false; |
| 1072 } | 1080 } |
| 1073 | 1081 |
| 1074 } // namespace blink | 1082 } // namespace blink |
| OLD | NEW |