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 | 6 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All |
7 rights reserved. | 7 rights reserved. |
8 | 8 |
9 This library is free software; you can redistribute it and/or | 9 This library is free software; you can redistribute it and/or |
10 modify it under the terms of the GNU Library General Public | 10 modify it under the terms of the GNU Library General Public |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include <cassert> | 29 #include <cassert> |
30 #include <memory> | 30 #include <memory> |
31 #include "platform/Histogram.h" | 31 #include "platform/Histogram.h" |
32 #include "platform/InstanceCounters.h" | 32 #include "platform/InstanceCounters.h" |
33 #include "platform/RuntimeEnabledFeatures.h" | 33 #include "platform/RuntimeEnabledFeatures.h" |
34 #include "platform/SharedBuffer.h" | 34 #include "platform/SharedBuffer.h" |
35 #include "platform/WebTaskRunner.h" | 35 #include "platform/WebTaskRunner.h" |
36 #include "platform/instrumentation/tracing/TraceEvent.h" | 36 #include "platform/instrumentation/tracing/TraceEvent.h" |
37 #include "platform/loader/fetch/CachedMetadata.h" | 37 #include "platform/loader/fetch/CachedMetadata.h" |
38 #include "platform/loader/fetch/CrossOriginAccessControl.h" | 38 #include "platform/loader/fetch/CrossOriginAccessControl.h" |
| 39 #include "platform/loader/fetch/FetchContext.h" |
39 #include "platform/loader/fetch/FetchInitiatorTypeNames.h" | 40 #include "platform/loader/fetch/FetchInitiatorTypeNames.h" |
40 #include "platform/loader/fetch/FetchRequest.h" | 41 #include "platform/loader/fetch/FetchRequest.h" |
41 #include "platform/loader/fetch/IntegrityMetadata.h" | 42 #include "platform/loader/fetch/IntegrityMetadata.h" |
42 #include "platform/loader/fetch/MemoryCache.h" | 43 #include "platform/loader/fetch/MemoryCache.h" |
43 #include "platform/loader/fetch/ResourceClient.h" | 44 #include "platform/loader/fetch/ResourceClient.h" |
44 #include "platform/loader/fetch/ResourceClientWalker.h" | 45 #include "platform/loader/fetch/ResourceClientWalker.h" |
45 #include "platform/loader/fetch/ResourceLoader.h" | 46 #include "platform/loader/fetch/ResourceLoader.h" |
46 #include "platform/network/HTTPParsers.h" | 47 #include "platform/network/HTTPParsers.h" |
47 #include "platform/weborigin/KURL.h" | 48 #include "platform/weborigin/KURL.h" |
48 #include "platform/wtf/CurrentTime.h" | 49 #include "platform/wtf/CurrentTime.h" |
49 #include "platform/wtf/MathExtras.h" | 50 #include "platform/wtf/MathExtras.h" |
50 #include "platform/wtf/StdLibExtras.h" | 51 #include "platform/wtf/StdLibExtras.h" |
51 #include "platform/wtf/Vector.h" | 52 #include "platform/wtf/Vector.h" |
52 #include "platform/wtf/text/CString.h" | 53 #include "platform/wtf/text/CString.h" |
53 #include "platform/wtf/text/StringBuilder.h" | 54 #include "platform/wtf/text/StringBuilder.h" |
54 #include "public/platform/Platform.h" | 55 #include "public/platform/Platform.h" |
55 #include "public/platform/WebCachePolicy.h" | 56 #include "public/platform/WebCachePolicy.h" |
56 #include "public/platform/WebScheduler.h" | 57 #include "public/platform/WebScheduler.h" |
57 #include "public/platform/WebSecurityOrigin.h" | 58 #include "public/platform/WebSecurityOrigin.h" |
58 | 59 |
59 namespace blink { | 60 namespace blink { |
60 | 61 |
| 62 namespace { |
| 63 |
| 64 class StaticResourceCallback final : public Resource::ResourceCallback { |
| 65 public: |
| 66 StaticResourceCallback(); |
| 67 ~StaticResourceCallback() override; |
| 68 void schedule(Resource*) override; |
| 69 void cancel(Resource*) override; |
| 70 bool isScheduled(Resource*) const override; |
| 71 |
| 72 private: |
| 73 void runTask(); |
| 74 |
| 75 TaskHandle m_taskHandle; |
| 76 HashSet<Persistent<Resource>> m_resourcesWithPendingClients; |
| 77 }; |
| 78 |
| 79 StaticResourceCallback::StaticResourceCallback() {} |
| 80 StaticResourceCallback::~StaticResourceCallback() {} |
| 81 |
| 82 void StaticResourceCallback::schedule(Resource* resource) { |
| 83 if (!m_taskHandle.isActive()) { |
| 84 // WTF::unretained(this) is safe because a posted task is canceled when |
| 85 // |m_taskHandle| is destroyed on the dtor of this ResourceCallback. |
| 86 m_taskHandle = |
| 87 Platform::current() |
| 88 ->currentThread() |
| 89 ->scheduler() |
| 90 ->loadingTaskRunner() |
| 91 ->postCancellableTask(BLINK_FROM_HERE, |
| 92 WTF::bind(&StaticResourceCallback::runTask, |
| 93 WTF::unretained(this))); |
| 94 } |
| 95 m_resourcesWithPendingClients.insert(resource); |
| 96 } |
| 97 |
| 98 void StaticResourceCallback::cancel(Resource* resource) { |
| 99 m_resourcesWithPendingClients.erase(resource); |
| 100 if (m_taskHandle.isActive() && m_resourcesWithPendingClients.isEmpty()) |
| 101 m_taskHandle.cancel(); |
| 102 } |
| 103 |
| 104 bool StaticResourceCallback::isScheduled(Resource* resource) const { |
| 105 return m_resourcesWithPendingClients.contains(resource); |
| 106 } |
| 107 |
| 108 void StaticResourceCallback::runTask() { |
| 109 HeapVector<Member<Resource>> resources; |
| 110 for (const Member<Resource>& resource : m_resourcesWithPendingClients) |
| 111 resources.push_back(resource.get()); |
| 112 m_resourcesWithPendingClients.clear(); |
| 113 |
| 114 for (const auto& resource : resources) |
| 115 resource->finishPendingClients(); |
| 116 } |
| 117 |
| 118 } // namespace |
| 119 |
61 // These response headers are not copied from a revalidated response to the | 120 // These response headers are not copied from a revalidated response to the |
62 // cached response headers. For compatibility, this list is based on Chromium's | 121 // cached response headers. For compatibility, this list is based on Chromium's |
63 // net/http/http_response_headers.cc. | 122 // net/http/http_response_headers.cc. |
64 const char* const headersToIgnoreAfterRevalidation[] = { | 123 const char* const headersToIgnoreAfterRevalidation[] = { |
65 "allow", | 124 "allow", |
66 "connection", | 125 "connection", |
67 "etag", | 126 "etag", |
68 "expires", | 127 "expires", |
69 "keep-alive", | 128 "keep-alive", |
70 "last-modified", | 129 "last-modified", |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 serializedData.size(), WebSecurityOrigin(m_securityOrigin), | 293 serializedData.size(), WebSecurityOrigin(m_securityOrigin), |
235 response().cacheStorageCacheName()); | 294 response().cacheStorageCacheName()); |
236 } else { | 295 } else { |
237 Platform::current()->cacheMetadataInCacheStorage( | 296 Platform::current()->cacheMetadataInCacheStorage( |
238 response().url(), response().responseTime(), nullptr, 0, | 297 response().url(), response().responseTime(), nullptr, 0, |
239 WebSecurityOrigin(m_securityOrigin), | 298 WebSecurityOrigin(m_securityOrigin), |
240 response().cacheStorageCacheName()); | 299 response().cacheStorageCacheName()); |
241 } | 300 } |
242 } | 301 } |
243 | 302 |
244 // This class cannot be on-heap because the first callbackHandler() call | |
245 // instantiates the singleton object while we can call it in the | |
246 // pre-finalization step. | |
247 class Resource::ResourceCallback final { | |
248 public: | |
249 static ResourceCallback& callbackHandler(); | |
250 void schedule(Resource*); | |
251 void cancel(Resource*); | |
252 bool isScheduled(Resource*) const; | |
253 | |
254 private: | |
255 ResourceCallback(); | |
256 | |
257 void runTask(); | |
258 TaskHandle m_taskHandle; | |
259 HashSet<Persistent<Resource>> m_resourcesWithPendingClients; | |
260 }; | |
261 | |
262 Resource::ResourceCallback& Resource::ResourceCallback::callbackHandler() { | |
263 DEFINE_STATIC_LOCAL(ResourceCallback, callbackHandler, ()); | |
264 return callbackHandler; | |
265 } | |
266 | |
267 Resource::ResourceCallback::ResourceCallback() {} | |
268 | |
269 void Resource::ResourceCallback::schedule(Resource* resource) { | |
270 if (!m_taskHandle.isActive()) { | |
271 // WTF::unretained(this) is safe because a posted task is canceled when | |
272 // |m_taskHandle| is destroyed on the dtor of this ResourceCallback. | |
273 m_taskHandle = | |
274 Platform::current() | |
275 ->currentThread() | |
276 ->scheduler() | |
277 ->loadingTaskRunner() | |
278 ->postCancellableTask( | |
279 BLINK_FROM_HERE, | |
280 WTF::bind(&ResourceCallback::runTask, WTF::unretained(this))); | |
281 } | |
282 m_resourcesWithPendingClients.insert(resource); | |
283 } | |
284 | |
285 void Resource::ResourceCallback::cancel(Resource* resource) { | |
286 m_resourcesWithPendingClients.erase(resource); | |
287 if (m_taskHandle.isActive() && m_resourcesWithPendingClients.isEmpty()) | |
288 m_taskHandle.cancel(); | |
289 } | |
290 | |
291 bool Resource::ResourceCallback::isScheduled(Resource* resource) const { | |
292 return m_resourcesWithPendingClients.contains(resource); | |
293 } | |
294 | |
295 void Resource::ResourceCallback::runTask() { | |
296 HeapVector<Member<Resource>> resources; | |
297 for (const Member<Resource>& resource : m_resourcesWithPendingClients) | |
298 resources.push_back(resource.get()); | |
299 m_resourcesWithPendingClients.clear(); | |
300 | |
301 for (const auto& resource : resources) | |
302 resource->finishPendingClients(); | |
303 } | |
304 | |
305 Resource::Resource(const ResourceRequest& request, | 303 Resource::Resource(const ResourceRequest& request, |
306 Type type, | 304 Type type, |
307 const ResourceLoaderOptions& options) | 305 const ResourceLoaderOptions& options, |
| 306 FetchContext* fetchContext) |
308 : m_loadFinishTime(0), | 307 : m_loadFinishTime(0), |
309 m_identifier(0), | 308 m_identifier(0), |
310 m_encodedSize(0), | 309 m_encodedSize(0), |
311 m_encodedSizeMemoryUsage(0), | 310 m_encodedSizeMemoryUsage(0), |
312 m_decodedSize(0), | 311 m_decodedSize(0), |
313 m_overheadSize(calculateOverheadSize()), | 312 m_overheadSize(calculateOverheadSize()), |
314 m_preloadCount(0), | 313 m_preloadCount(0), |
315 m_preloadDiscoveryTime(0.0), | 314 m_preloadDiscoveryTime(0.0), |
316 m_cacheIdentifier(MemoryCache::defaultCacheIdentifier()), | 315 m_cacheIdentifier(MemoryCache::defaultCacheIdentifier()), |
317 m_preloadResult(PreloadNotReferenced), | 316 m_preloadResult(PreloadNotReferenced), |
318 m_type(type), | 317 m_type(type), |
319 m_status(ResourceStatus::NotStarted), | 318 m_status(ResourceStatus::NotStarted), |
320 m_needsSynchronousCacheHit(false), | 319 m_needsSynchronousCacheHit(false), |
321 m_linkPreload(false), | 320 m_linkPreload(false), |
322 m_isRevalidating(false), | 321 m_isRevalidating(false), |
323 m_isAlive(false), | 322 m_isAlive(false), |
324 m_isAddRemoveClientProhibited(false), | 323 m_isAddRemoveClientProhibited(false), |
325 m_integrityDisposition(ResourceIntegrityDisposition::NotChecked), | 324 m_integrityDisposition(ResourceIntegrityDisposition::NotChecked), |
326 m_options(options), | 325 m_options(options), |
327 m_responseTimestamp(currentTime()), | 326 m_responseTimestamp(currentTime()), |
328 m_cancelTimer(Platform::current()->mainThread()->getWebTaskRunner(), | 327 m_cancelTimer(fetchContext && fetchContext->timerTaskRunner() |
| 328 ? fetchContext->timerTaskRunner() |
| 329 : Platform::current()->mainThread()->getWebTaskRunner(), |
329 this, | 330 this, |
330 &Resource::cancelTimerFired), | 331 &Resource::cancelTimerFired), |
| 332 m_fetchContext(fetchContext), |
331 m_resourceRequest(request) { | 333 m_resourceRequest(request) { |
332 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); | 334 InstanceCounters::incrementCounter(InstanceCounters::ResourceCounter); |
333 | 335 |
334 // Currently we support the metadata caching only for HTTP family. | 336 // Currently we support the metadata caching only for HTTP family. |
335 if (resourceRequest().url().protocolIsInHTTPFamily()) | 337 if (resourceRequest().url().protocolIsInHTTPFamily()) |
336 m_cacheHandler = CachedMetadataHandlerImpl::create(this); | 338 m_cacheHandler = CachedMetadataHandlerImpl::create(this); |
337 MemoryCoordinator::instance().registerClient(this); | 339 if (isMainThread()) |
| 340 MemoryCoordinator::instance().registerClient(this); |
338 } | 341 } |
339 | 342 |
340 Resource::~Resource() { | 343 Resource::~Resource() { |
341 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); | 344 InstanceCounters::decrementCounter(InstanceCounters::ResourceCounter); |
342 } | 345 } |
343 | 346 |
344 DEFINE_TRACE(Resource) { | 347 DEFINE_TRACE(Resource) { |
345 visitor->trace(m_loader); | 348 visitor->trace(m_loader); |
| 349 visitor->trace(m_fetchContext); |
346 visitor->trace(m_cacheHandler); | 350 visitor->trace(m_cacheHandler); |
347 visitor->trace(m_clients); | 351 visitor->trace(m_clients); |
348 visitor->trace(m_clientsAwaitingCallback); | 352 visitor->trace(m_clientsAwaitingCallback); |
349 visitor->trace(m_finishedClients); | 353 visitor->trace(m_finishedClients); |
350 MemoryCoordinatorClient::trace(visitor); | 354 MemoryCoordinatorClient::trace(visitor); |
351 } | 355 } |
352 | 356 |
353 void Resource::setLoader(ResourceLoader* loader) { | 357 void Resource::setLoader(ResourceLoader* loader) { |
354 CHECK(!m_loader); | 358 CHECK(!m_loader); |
355 DCHECK(stillNeedsLoad()); | 359 DCHECK(stillNeedsLoad()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 m_options.dataBufferingPolicy = dataBufferingPolicy; | 409 m_options.dataBufferingPolicy = dataBufferingPolicy; |
406 clearData(); | 410 clearData(); |
407 setEncodedSize(0); | 411 setEncodedSize(0); |
408 } | 412 } |
409 | 413 |
410 void Resource::error(const ResourceError& error) { | 414 void Resource::error(const ResourceError& error) { |
411 DCHECK(!error.isNull()); | 415 DCHECK(!error.isNull()); |
412 m_error = error; | 416 m_error = error; |
413 m_isRevalidating = false; | 417 m_isRevalidating = false; |
414 | 418 |
415 if (m_error.isCancellation() || !isPreloaded()) | 419 if ((m_error.isCancellation() || !isPreloaded()) && isMainThread()) |
416 memoryCache()->remove(this); | 420 memoryCache()->remove(this); |
417 | 421 |
418 if (!errorOccurred()) | 422 if (!errorOccurred()) |
419 setStatus(ResourceStatus::LoadError); | 423 setStatus(ResourceStatus::LoadError); |
420 DCHECK(errorOccurred()); | 424 DCHECK(errorOccurred()); |
421 clearData(); | 425 clearData(); |
422 m_loader = nullptr; | 426 m_loader = nullptr; |
423 checkNotify(); | 427 checkNotify(); |
424 } | 428 } |
425 | 429 |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 builder.append(' '); | 645 builder.append(' '); |
642 builder.append("m_loader"); | 646 builder.append("m_loader"); |
643 } | 647 } |
644 if (m_preloadCount) { | 648 if (m_preloadCount) { |
645 if (!builder.isEmpty()) | 649 if (!builder.isEmpty()) |
646 builder.append(' '); | 650 builder.append(' '); |
647 builder.append("m_preloadCount("); | 651 builder.append("m_preloadCount("); |
648 builder.appendNumber(m_preloadCount); | 652 builder.appendNumber(m_preloadCount); |
649 builder.append(')'); | 653 builder.append(')'); |
650 } | 654 } |
651 if (memoryCache()->contains(this)) { | 655 if (isMainThread() && memoryCache()->contains(this)) { |
652 if (!builder.isEmpty()) | 656 if (!builder.isEmpty()) |
653 builder.append(' '); | 657 builder.append(' '); |
654 builder.append("in_memory_cache"); | 658 builder.append("in_memory_cache"); |
655 } | 659 } |
656 return builder.toString(); | 660 return builder.toString(); |
657 } | 661 } |
658 | 662 |
659 void Resource::didAddClient(ResourceClient* c) { | 663 void Resource::didAddClient(ResourceClient* c) { |
660 if (isLoaded()) { | 664 if (isLoaded()) { |
661 c->notifyFinished(this); | 665 c->notifyFinished(this); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 if (m_isRevalidating) { | 719 if (m_isRevalidating) { |
716 m_clients.insert(client); | 720 m_clients.insert(client); |
717 return; | 721 return; |
718 } | 722 } |
719 | 723 |
720 // If an error has occurred or we have existing data to send to the new client | 724 // If an error has occurred or we have existing data to send to the new client |
721 // and the resource type supprts it, send it asynchronously. | 725 // and the resource type supprts it, send it asynchronously. |
722 if ((errorOccurred() || !response().isNull()) && | 726 if ((errorOccurred() || !response().isNull()) && |
723 !typeNeedsSynchronousCacheHit(getType()) && !m_needsSynchronousCacheHit) { | 727 !typeNeedsSynchronousCacheHit(getType()) && !m_needsSynchronousCacheHit) { |
724 m_clientsAwaitingCallback.insert(client); | 728 m_clientsAwaitingCallback.insert(client); |
725 ResourceCallback::callbackHandler().schedule(this); | 729 resourceCallback().schedule(this); |
726 return; | 730 return; |
727 } | 731 } |
728 | 732 |
729 m_clients.insert(client); | 733 m_clients.insert(client); |
730 didAddClient(client); | 734 didAddClient(client); |
731 return; | 735 return; |
732 } | 736 } |
733 | 737 |
734 void Resource::removeClient(ResourceClient* client) { | 738 void Resource::removeClient(ResourceClient* client) { |
735 CHECK(!m_isAddRemoveClientProhibited); | 739 CHECK(!m_isAddRemoveClientProhibited); |
736 | 740 |
737 // This code may be called in a pre-finalizer, where weak members in the | 741 // This code may be called in a pre-finalizer, where weak members in the |
738 // HashCountedSet are already swept out. | 742 // HashCountedSet are already swept out. |
739 | 743 |
740 if (m_finishedClients.contains(client)) | 744 if (m_finishedClients.contains(client)) |
741 m_finishedClients.erase(client); | 745 m_finishedClients.erase(client); |
742 else if (m_clientsAwaitingCallback.contains(client)) | 746 else if (m_clientsAwaitingCallback.contains(client)) |
743 m_clientsAwaitingCallback.erase(client); | 747 m_clientsAwaitingCallback.erase(client); |
744 else | 748 else |
745 m_clients.erase(client); | 749 m_clients.erase(client); |
746 | 750 |
747 if (m_clientsAwaitingCallback.isEmpty()) | 751 if (m_clientsAwaitingCallback.isEmpty()) |
748 ResourceCallback::callbackHandler().cancel(this); | 752 resourceCallback().cancel(this); |
749 | 753 |
750 didRemoveClientOrObserver(); | 754 didRemoveClientOrObserver(); |
751 } | 755 } |
752 | 756 |
753 void Resource::didRemoveClientOrObserver() { | 757 void Resource::didRemoveClientOrObserver() { |
754 if (!hasClientsOrObservers() && m_isAlive) { | 758 if (!hasClientsOrObservers() && m_isAlive) { |
755 m_isAlive = false; | 759 m_isAlive = false; |
756 allClientsAndObserversRemoved(); | 760 allClientsAndObserversRemoved(); |
757 | 761 |
758 // RFC2616 14.9.2: | 762 // RFC2616 14.9.2: |
759 // "no-store: ... MUST make a best-effort attempt to remove the information | 763 // "no-store: ... MUST make a best-effort attempt to remove the information |
760 // from volatile storage as promptly as possible" | 764 // from volatile storage as promptly as possible" |
761 // "... History buffers MAY store such responses as part of their normal | 765 // "... History buffers MAY store such responses as part of their normal |
762 // operation." | 766 // operation." |
763 // We allow non-secure content to be reused in history, but we do not allow | 767 // We allow non-secure content to be reused in history, but we do not allow |
764 // secure content to be reused. | 768 // secure content to be reused. |
765 if (hasCacheControlNoStoreHeader() && url().protocolIs("https")) | 769 if (hasCacheControlNoStoreHeader() && url().protocolIs("https") && |
| 770 isMainThread()) { |
766 memoryCache()->remove(this); | 771 memoryCache()->remove(this); |
| 772 } |
767 } | 773 } |
768 } | 774 } |
769 | 775 |
770 void Resource::allClientsAndObserversRemoved() { | 776 void Resource::allClientsAndObserversRemoved() { |
771 if (!m_loader) | 777 if (!m_loader) |
772 return; | 778 return; |
773 if (!m_cancelTimer.isActive()) | 779 if (!m_cancelTimer.isActive()) |
774 m_cancelTimer.startOneShot(0, BLINK_FROM_HERE); | 780 m_cancelTimer.startOneShot(0, BLINK_FROM_HERE); |
775 } | 781 } |
776 | 782 |
777 void Resource::cancelTimerFired(TimerBase* timer) { | 783 void Resource::cancelTimerFired(TimerBase* timer) { |
778 DCHECK_EQ(timer, &m_cancelTimer); | 784 DCHECK_EQ(timer, &m_cancelTimer); |
779 if (!hasClientsOrObservers() && m_loader) | 785 if (!hasClientsOrObservers() && m_loader) |
780 m_loader->cancel(); | 786 m_loader->cancel(); |
781 } | 787 } |
782 | 788 |
783 void Resource::setDecodedSize(size_t decodedSize) { | 789 void Resource::setDecodedSize(size_t decodedSize) { |
784 if (decodedSize == m_decodedSize) | 790 if (decodedSize == m_decodedSize) |
785 return; | 791 return; |
786 size_t oldSize = size(); | 792 size_t oldSize = size(); |
787 m_decodedSize = decodedSize; | 793 m_decodedSize = decodedSize; |
788 memoryCache()->update(this, oldSize, size()); | 794 if (isMainThread()) |
| 795 memoryCache()->update(this, oldSize, size()); |
789 } | 796 } |
790 | 797 |
791 void Resource::setEncodedSize(size_t encodedSize) { | 798 void Resource::setEncodedSize(size_t encodedSize) { |
792 if (encodedSize == m_encodedSize && encodedSize == m_encodedSizeMemoryUsage) | 799 if (encodedSize == m_encodedSize && encodedSize == m_encodedSizeMemoryUsage) |
793 return; | 800 return; |
794 size_t oldSize = size(); | 801 size_t oldSize = size(); |
795 m_encodedSize = encodedSize; | 802 m_encodedSize = encodedSize; |
796 m_encodedSizeMemoryUsage = encodedSize; | 803 m_encodedSizeMemoryUsage = encodedSize; |
797 memoryCache()->update(this, oldSize, size()); | 804 if (isMainThread()) |
| 805 memoryCache()->update(this, oldSize, size()); |
798 } | 806 } |
799 | 807 |
800 void Resource::finishPendingClients() { | 808 void Resource::finishPendingClients() { |
801 // We're going to notify clients one by one. It is simple if the client does | 809 // We're going to notify clients one by one. It is simple if the client does |
802 // nothing. However there are a couple other things that can happen. | 810 // nothing. However there are a couple other things that can happen. |
803 // | 811 // |
804 // 1. Clients can be added during the loop. Make sure they are not processed. | 812 // 1. Clients can be added during the loop. Make sure they are not processed. |
805 // 2. Clients can be removed during the loop. Make sure they are always | 813 // 2. Clients can be removed during the loop. Make sure they are always |
806 // available to be removed. Also don't call removed clients or add them | 814 // available to be removed. Also don't call removed clients or add them |
807 // back. | 815 // back. |
(...skipping 11 matching lines...) Expand all Loading... |
819 | 827 |
820 // When revalidation starts after waiting clients are scheduled and | 828 // When revalidation starts after waiting clients are scheduled and |
821 // before they are added here. In such cases, we just add the clients | 829 // before they are added here. In such cases, we just add the clients |
822 // to |m_clients| without didAddClient(), as in Resource::addClient(). | 830 // to |m_clients| without didAddClient(), as in Resource::addClient(). |
823 if (!m_isRevalidating) | 831 if (!m_isRevalidating) |
824 didAddClient(client); | 832 didAddClient(client); |
825 } | 833 } |
826 | 834 |
827 // It is still possible for the above loop to finish a new client | 835 // It is still possible for the above loop to finish a new client |
828 // synchronously. If there's no client waiting we should deschedule. | 836 // synchronously. If there's no client waiting we should deschedule. |
829 bool scheduled = ResourceCallback::callbackHandler().isScheduled(this); | 837 bool scheduled = resourceCallback().isScheduled(this); |
830 if (scheduled && m_clientsAwaitingCallback.isEmpty()) | 838 if (scheduled && m_clientsAwaitingCallback.isEmpty()) |
831 ResourceCallback::callbackHandler().cancel(this); | 839 resourceCallback().cancel(this); |
832 | 840 |
833 // Prevent the case when there are clients waiting but no callback scheduled. | 841 // Prevent the case when there are clients waiting but no callback scheduled. |
834 DCHECK(m_clientsAwaitingCallback.isEmpty() || scheduled); | 842 DCHECK(m_clientsAwaitingCallback.isEmpty() || scheduled); |
835 } | 843 } |
836 | 844 |
837 void Resource::prune() { | 845 void Resource::prune() { |
838 destroyDecodedDataIfPossible(); | 846 destroyDecodedDataIfPossible(); |
839 } | 847 } |
840 | 848 |
841 void Resource::onPurgeMemory() { | 849 void Resource::onPurgeMemory() { |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1118 case Resource::TextTrack: | 1126 case Resource::TextTrack: |
1119 case Resource::Media: | 1127 case Resource::Media: |
1120 case Resource::Manifest: | 1128 case Resource::Manifest: |
1121 case Resource::Mock: | 1129 case Resource::Mock: |
1122 return false; | 1130 return false; |
1123 } | 1131 } |
1124 NOTREACHED(); | 1132 NOTREACHED(); |
1125 return false; | 1133 return false; |
1126 } | 1134 } |
1127 | 1135 |
| 1136 Resource::ResourceCallback& Resource::resourceCallback() { |
| 1137 if (m_fetchContext && m_fetchContext->resourceCallback()) { |
| 1138 DCHECK(!isMainThread()); |
| 1139 return *m_fetchContext->resourceCallback(); |
| 1140 } |
| 1141 DCHECK(isMainThread()); |
| 1142 DEFINE_STATIC_LOCAL(StaticResourceCallback, callbackHandler, ()); |
| 1143 return callbackHandler; |
| 1144 } |
| 1145 |
1128 } // namespace blink | 1146 } // namespace blink |
OLD | NEW |