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) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. | 5 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. |
6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ | 6 Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ |
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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 return WebURLRequest::RequestContextImage; | 159 return WebURLRequest::RequestContextImage; |
160 case Resource::Media: // TODO: Split this. | 160 case Resource::Media: // TODO: Split this. |
161 return WebURLRequest::RequestContextVideo; | 161 return WebURLRequest::RequestContextVideo; |
162 } | 162 } |
163 ASSERT_NOT_REACHED(); | 163 ASSERT_NOT_REACHED(); |
164 return WebURLRequest::RequestContextSubresource; | 164 return WebURLRequest::RequestContextSubresource; |
165 } | 165 } |
166 | 166 |
167 ResourceFetcher::ResourceFetcher(FetchContext* context) | 167 ResourceFetcher::ResourceFetcher(FetchContext* context) |
168 : m_context(context) | 168 : m_context(context) |
169 , m_garbageCollectDocumentResourcesTimer(this, &ResourceFetcher::garbageColl ectDocumentResourcesTimerFired) | |
170 , m_resourceTimingReportTimer(this, &ResourceFetcher::resourceTimingReportTi merFired) | 169 , m_resourceTimingReportTimer(this, &ResourceFetcher::resourceTimingReportTi merFired) |
171 , m_autoLoadImages(true) | 170 , m_autoLoadImages(true) |
172 , m_imagesEnabled(true) | 171 , m_imagesEnabled(true) |
173 , m_allowStaleResources(false) | 172 , m_allowStaleResources(false) |
174 { | 173 { |
175 #if ENABLE(OILPAN) | 174 #if ENABLE(OILPAN) |
176 ThreadState::current()->registerPreFinalizer(this); | 175 ThreadState::current()->registerPreFinalizer(this); |
177 #endif | 176 #endif |
178 } | 177 } |
179 | 178 |
180 ResourceFetcher::~ResourceFetcher() | 179 ResourceFetcher::~ResourceFetcher() |
181 { | 180 { |
182 #if !ENABLE(OILPAN) | 181 #if !ENABLE(OILPAN) |
183 clearPreloads(); | 182 clearPreloads(); |
184 #endif | 183 #endif |
185 } | 184 } |
186 | 185 |
187 WebTaskRunner* ResourceFetcher::loadingTaskRunner() | 186 WebTaskRunner* ResourceFetcher::loadingTaskRunner() |
188 { | 187 { |
189 if (!m_context) | 188 if (!m_context) |
190 return nullptr; | 189 return nullptr; |
191 | 190 |
192 return m_context->loadingTaskRunner(); | 191 return m_context->loadingTaskRunner(); |
193 } | 192 } |
194 | 193 |
195 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const | 194 Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const |
196 { | 195 { |
197 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL); | 196 KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL); |
198 return m_documentResources.get(url).get(); | 197 const WeakPtrWillBeWeakMember<Resource>& resource = m_documentResources.get( url); |
Nate Chapin
2015/12/14 23:12:16
WeakMember is smarter than WeakPtr about HashMap r
sof
2015/12/15 10:08:01
Traits are in place to unwrap the WeakMember on ge
| |
198 return resource.get(); | |
199 } | 199 } |
200 | 200 |
201 bool ResourceFetcher::canAccessResource(Resource* resource, SecurityOrigin* sour ceOrigin, const KURL& url, AccessControlLoggingDecision logErrorsDecision) const | 201 bool ResourceFetcher::canAccessResource(Resource* resource, SecurityOrigin* sour ceOrigin, const KURL& url, AccessControlLoggingDecision logErrorsDecision) const |
202 { | 202 { |
203 // Redirects can change the response URL different from one of request. | 203 // Redirects can change the response URL different from one of request. |
204 bool forPreload = resource->isUnusedPreload(); | 204 bool forPreload = resource->isUnusedPreload(); |
205 if (!context().canRequest(resource->type(), resource->resourceRequest(), url , resource->options(), forPreload, FetchRequest::UseDefaultOriginRestrictionForT ype)) | 205 if (!context().canRequest(resource->type(), resource->resourceRequest(), url , resource->options(), forPreload, FetchRequest::UseDefaultOriginRestrictionForT ype)) |
206 return false; | 206 return false; |
207 | 207 |
208 if (!sourceOrigin) | 208 if (!sourceOrigin) |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 resource->setOptions(request.options()); | 314 resource->setOptions(request.options()); |
315 // FIXME: We should provide a body stream here. | 315 // FIXME: We should provide a body stream here. |
316 resource->responseReceived(response, nullptr); | 316 resource->responseReceived(response, nullptr); |
317 resource->setDataBufferingPolicy(BufferData); | 317 resource->setDataBufferingPolicy(BufferData); |
318 if (data->size()) | 318 if (data->size()) |
319 resource->setResourceBuffer(data); | 319 resource->setResourceBuffer(data); |
320 resource->setIdentifier(createUniqueIdentifier()); | 320 resource->setIdentifier(createUniqueIdentifier()); |
321 resource->setCacheIdentifier(cacheIdentifier); | 321 resource->setCacheIdentifier(cacheIdentifier); |
322 resource->finish(); | 322 resource->finish(); |
323 memoryCache()->add(resource.get()); | 323 memoryCache()->add(resource.get()); |
324 scheduleDocumentResourcesGC(); | |
325 } | 324 } |
326 | 325 |
327 void ResourceFetcher::moveCachedNonBlockingResourceToBlocking(Resource* resource ) | 326 void ResourceFetcher::moveCachedNonBlockingResourceToBlocking(Resource* resource ) |
328 { | 327 { |
329 // TODO(yoav): Test that non-blocking resources (video/audio/track) continue to not-block even after being preloaded and discovered. | 328 // TODO(yoav): Test that non-blocking resources (video/audio/track) continue to not-block even after being preloaded and discovered. |
330 if (resource && resource->loader() && resource->isNonBlockingResourceType() && resource->avoidBlockingOnLoad()) { | 329 if (resource && resource->loader() && resource->isNonBlockingResourceType() && resource->avoidBlockingOnLoad()) { |
331 if (m_nonBlockingLoaders) | 330 if (m_nonBlockingLoaders) |
332 m_nonBlockingLoaders->remove(resource->loader()); | 331 m_nonBlockingLoaders->remove(resource->loader()); |
333 if (!m_loaders) | 332 if (!m_loaders) |
334 m_loaders = ResourceLoaderSet::create(); | 333 m_loaders = ResourceLoaderSet::create(); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
451 // Remove main resource from cache to prevent reuse. | 450 // Remove main resource from cache to prevent reuse. |
452 if (factory.type() == Resource::MainResource) { | 451 if (factory.type() == Resource::MainResource) { |
453 ASSERT(policy != Use || isStaticData); | 452 ASSERT(policy != Use || isStaticData); |
454 ASSERT(policy != Revalidate); | 453 ASSERT(policy != Revalidate); |
455 memoryCache()->remove(resource.get()); | 454 memoryCache()->remove(resource.get()); |
456 } | 455 } |
457 | 456 |
458 requestLoadStarted(resource.get(), request, policy == Use ? ResourceLoadingF romCache : ResourceLoadingFromNetwork, isStaticData); | 457 requestLoadStarted(resource.get(), request, policy == Use ? ResourceLoadingF romCache : ResourceLoadingFromNetwork, isStaticData); |
459 | 458 |
460 ASSERT(resource->url() == url.string()); | 459 ASSERT(resource->url() == url.string()); |
461 m_documentResources.set(resource->url(), resource); | 460 m_documentResources.set(resource->url(), resource->asWeakPtr()); |
462 return resource; | 461 return resource; |
463 } | 462 } |
464 | 463 |
465 void ResourceFetcher::resourceTimingReportTimerFired(Timer<ResourceFetcher>* tim er) | 464 void ResourceFetcher::resourceTimingReportTimerFired(Timer<ResourceFetcher>* tim er) |
466 { | 465 { |
467 ASSERT_UNUSED(timer, timer == &m_resourceTimingReportTimer); | 466 ASSERT_UNUSED(timer, timer == &m_resourceTimingReportTimer); |
468 Vector<OwnPtr<ResourceTimingInfo>> timingReports; | 467 Vector<OwnPtr<ResourceTimingInfo>> timingReports; |
469 timingReports.swap(m_scheduledResourceTimingReports); | 468 timingReports.swap(m_scheduledResourceTimingReports); |
470 for (const auto& timingInfo : timingReports) | 469 for (const auto& timingInfo : timingReports) |
471 context().addResourceTiming(*timingInfo); | 470 context().addResourceTiming(*timingInfo); |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
763 return !context().allowImage(m_imagesEnabled, url); | 762 return !context().allowImage(m_imagesEnabled, url); |
764 } | 763 } |
765 | 764 |
766 bool ResourceFetcher::shouldDeferImageLoad(const KURL& url) const | 765 bool ResourceFetcher::shouldDeferImageLoad(const KURL& url) const |
767 { | 766 { |
768 return clientDefersImage(url) || !m_autoLoadImages; | 767 return clientDefersImage(url) || !m_autoLoadImages; |
769 } | 768 } |
770 | 769 |
771 void ResourceFetcher::reloadImagesIfNotDeferred() | 770 void ResourceFetcher::reloadImagesIfNotDeferred() |
772 { | 771 { |
773 for (const auto& documentResource : m_documentResources) { | 772 for (const auto& documentResource : m_documentResources) { |
sof
2015/12/15 12:29:45
This can be simplified some once we can assume Oil
Nate Chapin
2015/12/15 20:30:59
Done.
| |
774 Resource* resource = documentResource.value.get(); | 773 Resource* resource = documentResource.value.get(); |
775 if (resource->type() == Resource::Image && resource->stillNeedsLoad() && !clientDefersImage(resource->url())) | 774 if (resource && resource->type() == Resource::Image && resource->stillNe edsLoad() && !clientDefersImage(resource->url())) |
776 const_cast<Resource*>(resource)->load(this, defaultResourceOptions() ); | 775 const_cast<Resource*>(resource)->load(this, defaultResourceOptions() ); |
777 } | 776 } |
778 } | 777 } |
779 | 778 |
780 void ResourceFetcher::redirectReceived(Resource* resource, const ResourceRespons e& redirectResponse) | 779 void ResourceFetcher::redirectReceived(Resource* resource, const ResourceRespons e& redirectResponse) |
781 { | 780 { |
782 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); | 781 ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource); |
783 if (it != m_resourceTimingInfoMap.end()) | 782 if (it != m_resourceTimingInfoMap.end()) |
784 it->value->addRedirect(redirectResponse); | 783 it->value->addRedirect(redirectResponse); |
785 } | 784 } |
786 | 785 |
787 void ResourceFetcher::didLoadResource() | 786 void ResourceFetcher::didLoadResource() |
788 { | 787 { |
789 scheduleDocumentResourcesGC(); | |
790 context().didLoadResource(); | 788 context().didLoadResource(); |
791 } | 789 } |
792 | 790 |
793 void ResourceFetcher::scheduleDocumentResourcesGC() | |
794 { | |
795 if (!m_garbageCollectDocumentResourcesTimer.isActive()) | |
796 m_garbageCollectDocumentResourcesTimer.startOneShot(0, BLINK_FROM_HERE); | |
797 } | |
798 | |
799 // Garbage collecting m_documentResources is a workaround for the | |
800 // ResourcePtrs on the RHS being strong references. Ideally this | |
801 // would be a weak map, however ResourcePtrs perform additional | |
802 // bookkeeping on Resources, so instead pseudo-GC them -- when the | |
803 // reference count reaches 1, m_documentResources is the only reference, so | |
804 // remove it from the map. | |
805 void ResourceFetcher::garbageCollectDocumentResourcesTimerFired(Timer<ResourceFe tcher>* timer) | |
806 { | |
807 ASSERT_UNUSED(timer, timer == &m_garbageCollectDocumentResourcesTimer); | |
808 garbageCollectDocumentResources(); | |
809 } | |
810 | |
811 void ResourceFetcher::garbageCollectDocumentResources() | |
812 { | |
813 typedef Vector<String, 10> StringVector; | |
814 StringVector resourcesToDelete; | |
815 | |
816 for (const auto& documentResource : m_documentResources) { | |
817 if (documentResource.value->hasOneHandle()) | |
818 resourcesToDelete.append(documentResource.key); | |
819 } | |
820 | |
821 m_documentResources.removeAll(resourcesToDelete); | |
822 } | |
823 | |
824 int ResourceFetcher::requestCount() const | 791 int ResourceFetcher::requestCount() const |
825 { | 792 { |
826 return m_loaders ? m_loaders->size() : 0; | 793 return m_loaders ? m_loaders->size() : 0; |
827 } | 794 } |
828 | 795 |
829 void ResourceFetcher::preloadStarted(Resource* resource) | 796 void ResourceFetcher::preloadStarted(Resource* resource) |
830 { | 797 { |
831 if (m_preloads && m_preloads->contains(resource)) | 798 if (m_preloads && m_preloads->contains(resource)) |
832 return; | 799 return; |
833 TRACE_EVENT_ASYNC_STEP_INTO0("blink.net", "Resource", resource, "Preload"); | 800 TRACE_EVENT_ASYNC_STEP_INTO0("blink.net", "Resource", resource, "Preload"); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1175 } | 1142 } |
1176 } | 1143 } |
1177 | 1144 |
1178 DEFINE_TRACE(ResourceFetcher) | 1145 DEFINE_TRACE(ResourceFetcher) |
1179 { | 1146 { |
1180 visitor->trace(m_context); | 1147 visitor->trace(m_context); |
1181 visitor->trace(m_archiveResourceCollection); | 1148 visitor->trace(m_archiveResourceCollection); |
1182 visitor->trace(m_loaders); | 1149 visitor->trace(m_loaders); |
1183 visitor->trace(m_nonBlockingLoaders); | 1150 visitor->trace(m_nonBlockingLoaders); |
1184 #if ENABLE(OILPAN) | 1151 #if ENABLE(OILPAN) |
1152 visitor->trace(m_documentResources); | |
1185 visitor->trace(m_preloads); | 1153 visitor->trace(m_preloads); |
1186 visitor->trace(m_resourceTimingInfoMap); | 1154 visitor->trace(m_resourceTimingInfoMap); |
1187 #endif | 1155 #endif |
1188 } | 1156 } |
1189 | 1157 |
1190 } | 1158 } |
OLD | NEW |