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 |