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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 CachedMetadata* Resource::CacheHandler::cachedMetadata(unsigned dataTypeID) cons
t | 137 CachedMetadata* Resource::CacheHandler::cachedMetadata(unsigned dataTypeID) cons
t |
138 { | 138 { |
139 return m_resource->cachedMetadata(dataTypeID); | 139 return m_resource->cachedMetadata(dataTypeID); |
140 } | 140 } |
141 | 141 |
142 String Resource::CacheHandler::encoding() const | 142 String Resource::CacheHandler::encoding() const |
143 { | 143 { |
144 return m_resource->encoding(); | 144 return m_resource->encoding(); |
145 } | 145 } |
146 | 146 |
| 147 class Resource::ResourceCallback final : public GarbageCollectedFinalized<Resour
ceCallback> { |
| 148 public: |
| 149 static ResourceCallback& callbackHandler(); |
| 150 DECLARE_TRACE(); |
| 151 void schedule(Resource*); |
| 152 void cancel(Resource*); |
| 153 bool isScheduled(Resource*) const; |
| 154 private: |
| 155 ResourceCallback(); |
| 156 |
| 157 void runTask(); |
| 158 OwnPtr<CancellableTaskFactory> m_callbackTaskFactory; |
| 159 HeapHashSet<Member<Resource>> m_resourcesWithPendingClients; |
| 160 }; |
| 161 |
| 162 Resource::ResourceCallback& Resource::ResourceCallback::callbackHandler() |
| 163 { |
| 164 // Oilpan + LSan: as the callbackHandler() singleton is used by Resource |
| 165 // and ResourcePtr finalizers, it cannot be released upon shutdown in |
| 166 // preparation for leak detection. |
| 167 // |
| 168 // Keep it out of LSan's reach instead. |
| 169 LEAK_SANITIZER_DISABLED_SCOPE; |
| 170 DEFINE_STATIC_LOCAL(ResourceCallback, callbackHandler, (new ResourceCallback
)); |
| 171 return callbackHandler; |
| 172 } |
| 173 |
| 174 DEFINE_TRACE(Resource::ResourceCallback) |
| 175 { |
| 176 visitor->trace(m_resourcesWithPendingClients); |
| 177 } |
| 178 |
| 179 Resource::ResourceCallback::ResourceCallback() |
| 180 : m_callbackTaskFactory(CancellableTaskFactory::create(this, &ResourceCallba
ck::runTask)) |
| 181 { |
| 182 } |
| 183 |
| 184 void Resource::ResourceCallback::schedule(Resource* resource) |
| 185 { |
| 186 if (!m_callbackTaskFactory->isPending()) |
| 187 Platform::current()->currentThread()->scheduler()->loadingTaskRunner()->
postTask(BLINK_FROM_HERE, m_callbackTaskFactory->cancelAndCreate()); |
| 188 m_resourcesWithPendingClients.add(resource); |
| 189 } |
| 190 |
| 191 void Resource::ResourceCallback::cancel(Resource* resource) |
| 192 { |
| 193 m_resourcesWithPendingClients.remove(resource); |
| 194 if (m_callbackTaskFactory->isPending() && m_resourcesWithPendingClients.isEm
pty()) |
| 195 m_callbackTaskFactory->cancel(); |
| 196 } |
| 197 |
| 198 bool Resource::ResourceCallback::isScheduled(Resource* resource) const |
| 199 { |
| 200 return m_resourcesWithPendingClients.contains(resource); |
| 201 } |
| 202 |
| 203 void Resource::ResourceCallback::runTask() |
| 204 { |
| 205 HeapVector<Member<Resource>> resources; |
| 206 for (const Member<Resource>& resource : m_resourcesWithPendingClients) |
| 207 resources.append(resource.get()); |
| 208 m_resourcesWithPendingClients.clear(); |
| 209 |
| 210 for (const auto& resource : resources) |
| 211 resource->finishPendingClients(); |
| 212 } |
| 213 |
147 Resource::Resource(const ResourceRequest& request, Type type, const ResourceLoad
erOptions& options) | 214 Resource::Resource(const ResourceRequest& request, Type type, const ResourceLoad
erOptions& options) |
148 : m_resourceRequest(request) | 215 : m_resourceRequest(request) |
149 , m_options(options) | 216 , m_options(options) |
150 , m_responseTimestamp(currentTime()) | 217 , m_responseTimestamp(currentTime()) |
151 , m_cancelTimer(this, &Resource::cancelTimerFired) | 218 , m_cancelTimer(this, &Resource::cancelTimerFired) |
152 #if !ENABLE(OILPAN) | 219 #if !ENABLE(OILPAN) |
153 , m_weakPtrFactory(this) | 220 , m_weakPtrFactory(this) |
154 #endif | 221 #endif |
155 , m_loadFinishTime(0) | 222 , m_loadFinishTime(0) |
156 , m_identifier(0) | 223 , m_identifier(0) |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 willAddClientOrObserver(); | 669 willAddClientOrObserver(); |
603 | 670 |
604 if (!m_revalidatingRequest.isNull()) { | 671 if (!m_revalidatingRequest.isNull()) { |
605 m_clients.add(client); | 672 m_clients.add(client); |
606 return; | 673 return; |
607 } | 674 } |
608 | 675 |
609 // If we have existing data to send to the new client and the resource type
supprts it, send it asynchronously. | 676 // If we have existing data to send to the new client and the resource type
supprts it, send it asynchronously. |
610 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(getTyp
e()) && !m_needsSynchronousCacheHit) { | 677 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(getTyp
e()) && !m_needsSynchronousCacheHit) { |
611 m_clientsAwaitingCallback.add(client); | 678 m_clientsAwaitingCallback.add(client); |
612 ResourceCallback::callbackHandler()->schedule(this); | 679 ResourceCallback::callbackHandler().schedule(this); |
613 return; | 680 return; |
614 } | 681 } |
615 | 682 |
616 m_clients.add(client); | 683 m_clients.add(client); |
617 didAddClient(client); | 684 didAddClient(client); |
618 return; | 685 return; |
619 } | 686 } |
620 | 687 |
621 void Resource::removeClient(ResourceClient* client) | 688 void Resource::removeClient(ResourceClient* client) |
622 { | 689 { |
623 ASSERT(hasClient(client)); | 690 ASSERT(hasClient(client)); |
624 if (m_finishedClients.contains(client)) | 691 if (m_finishedClients.contains(client)) |
625 m_finishedClients.remove(client); | 692 m_finishedClients.remove(client); |
626 else if (m_clientsAwaitingCallback.contains(client)) | 693 else if (m_clientsAwaitingCallback.contains(client)) |
627 m_clientsAwaitingCallback.remove(client); | 694 m_clientsAwaitingCallback.remove(client); |
628 else | 695 else |
629 m_clients.remove(client); | 696 m_clients.remove(client); |
630 | 697 |
631 if (m_clientsAwaitingCallback.isEmpty()) | 698 if (m_clientsAwaitingCallback.isEmpty()) |
632 ResourceCallback::callbackHandler()->cancel(this); | 699 ResourceCallback::callbackHandler().cancel(this); |
633 | 700 |
634 didRemoveClientOrObserver(); | 701 didRemoveClientOrObserver(); |
635 // This object may be dead here. | 702 // This object may be dead here. |
636 } | 703 } |
637 | 704 |
638 void Resource::didRemoveClientOrObserver() | 705 void Resource::didRemoveClientOrObserver() |
639 { | 706 { |
640 if (!hasClientsOrObservers()) { | 707 if (!hasClientsOrObservers()) { |
641 RawPtr<Resource> protect(this); | 708 RawPtr<Resource> protect(this); |
642 memoryCache()->makeDead(this); | 709 memoryCache()->makeDead(this); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 for (const auto& client : clientsToNotify) { | 787 for (const auto& client : clientsToNotify) { |
721 // Handle case (2) to skip removed clients. | 788 // Handle case (2) to skip removed clients. |
722 if (!m_clientsAwaitingCallback.remove(client)) | 789 if (!m_clientsAwaitingCallback.remove(client)) |
723 continue; | 790 continue; |
724 m_clients.add(client); | 791 m_clients.add(client); |
725 didAddClient(client); | 792 didAddClient(client); |
726 } | 793 } |
727 | 794 |
728 // It is still possible for the above loop to finish a new client synchronou
sly. | 795 // It is still possible for the above loop to finish a new client synchronou
sly. |
729 // If there's no client waiting we should deschedule. | 796 // If there's no client waiting we should deschedule. |
730 bool scheduled = ResourceCallback::callbackHandler()->isScheduled(this); | 797 bool scheduled = ResourceCallback::callbackHandler().isScheduled(this); |
731 if (scheduled && m_clientsAwaitingCallback.isEmpty()) | 798 if (scheduled && m_clientsAwaitingCallback.isEmpty()) |
732 ResourceCallback::callbackHandler()->cancel(this); | 799 ResourceCallback::callbackHandler().cancel(this); |
733 | 800 |
734 // Prevent the case when there are clients waiting but no callback scheduled
. | 801 // Prevent the case when there are clients waiting but no callback scheduled
. |
735 ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled); | 802 ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled); |
736 } | 803 } |
737 | 804 |
738 void Resource::prune() | 805 void Resource::prune() |
739 { | 806 { |
740 destroyDecodedDataIfPossible(); | 807 destroyDecodedDataIfPossible(); |
741 unlock(); | 808 unlock(); |
742 } | 809 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 return sizeof(Resource) + m_response.memoryUsage() + kAverageClientsHashMapS
ize + m_resourceRequest.url().getString().length() * 2; | 972 return sizeof(Resource) + m_response.memoryUsage() + kAverageClientsHashMapS
ize + m_resourceRequest.url().getString().length() * 2; |
906 } | 973 } |
907 | 974 |
908 void Resource::didChangePriority(ResourceLoadPriority loadPriority, int intraPri
orityValue) | 975 void Resource::didChangePriority(ResourceLoadPriority loadPriority, int intraPri
orityValue) |
909 { | 976 { |
910 m_resourceRequest.setPriority(loadPriority, intraPriorityValue); | 977 m_resourceRequest.setPriority(loadPriority, intraPriorityValue); |
911 if (m_loader) | 978 if (m_loader) |
912 m_loader->didChangePriority(loadPriority, intraPriorityValue); | 979 m_loader->didChangePriority(loadPriority, intraPriorityValue); |
913 } | 980 } |
914 | 981 |
915 Resource::ResourceCallback* Resource::ResourceCallback::callbackHandler() | |
916 { | |
917 // Oilpan + LSan: as the callbackHandler() singleton is used by Resource | |
918 // and ResourcePtr finalizers, it cannot be released upon shutdown in | |
919 // preparation for leak detection. | |
920 // | |
921 // Keep it out of LSan's reach instead. | |
922 LEAK_SANITIZER_DISABLED_SCOPE; | |
923 DEFINE_STATIC_LOCAL(Persistent<ResourceCallback>, callbackHandler, (new Reso
urceCallback)); | |
924 return callbackHandler.get(); | |
925 } | |
926 | |
927 DEFINE_TRACE(Resource::ResourceCallback) | |
928 { | |
929 #if ENABLE(OILPAN) | |
930 visitor->trace(m_resourcesWithPendingClients); | |
931 #endif | |
932 } | |
933 | |
934 Resource::ResourceCallback::ResourceCallback() | |
935 : m_callbackTaskFactory(CancellableTaskFactory::create(this, &ResourceCallba
ck::runTask)) | |
936 { | |
937 } | |
938 | |
939 void Resource::ResourceCallback::schedule(Resource* resource) | |
940 { | |
941 if (!m_callbackTaskFactory->isPending()) | |
942 Platform::current()->currentThread()->scheduler()->loadingTaskRunner()->
postTask(BLINK_FROM_HERE, m_callbackTaskFactory->cancelAndCreate()); | |
943 m_resourcesWithPendingClients.add(resource); | |
944 } | |
945 | |
946 void Resource::ResourceCallback::cancel(Resource* resource) | |
947 { | |
948 m_resourcesWithPendingClients.remove(resource); | |
949 if (m_callbackTaskFactory->isPending() && m_resourcesWithPendingClients.isEm
pty()) | |
950 m_callbackTaskFactory->cancel(); | |
951 } | |
952 | |
953 bool Resource::ResourceCallback::isScheduled(Resource* resource) const | |
954 { | |
955 return m_resourcesWithPendingClients.contains(resource); | |
956 } | |
957 | |
958 void Resource::ResourceCallback::runTask() | |
959 { | |
960 HeapVector<Member<Resource>> resources; | |
961 for (const Member<Resource>& resource : m_resourcesWithPendingClients) | |
962 resources.append(resource.get()); | |
963 m_resourcesWithPendingClients.clear(); | |
964 | |
965 for (const auto& resource : resources) | |
966 resource->finishPendingClients(); | |
967 } | |
968 | |
969 static const char* initatorTypeNameToString(const AtomicString& initiatorTypeNam
e) | 982 static const char* initatorTypeNameToString(const AtomicString& initiatorTypeNam
e) |
970 { | 983 { |
971 if (initiatorTypeName == FetchInitiatorTypeNames::css) | 984 if (initiatorTypeName == FetchInitiatorTypeNames::css) |
972 return "CSS resource"; | 985 return "CSS resource"; |
973 if (initiatorTypeName == FetchInitiatorTypeNames::document) | 986 if (initiatorTypeName == FetchInitiatorTypeNames::document) |
974 return "Document"; | 987 return "Document"; |
975 if (initiatorTypeName == FetchInitiatorTypeNames::icon) | 988 if (initiatorTypeName == FetchInitiatorTypeNames::icon) |
976 return "Icon"; | 989 return "Icon"; |
977 if (initiatorTypeName == FetchInitiatorTypeNames::internal) | 990 if (initiatorTypeName == FetchInitiatorTypeNames::internal) |
978 return "Internal resource"; | 991 return "Internal resource"; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1087 case Resource::Media: | 1100 case Resource::Media: |
1088 return "Media"; | 1101 return "Media"; |
1089 case Resource::Manifest: | 1102 case Resource::Manifest: |
1090 return "Manifest"; | 1103 return "Manifest"; |
1091 } | 1104 } |
1092 ASSERT_NOT_REACHED(); | 1105 ASSERT_NOT_REACHED(); |
1093 return "Unknown"; | 1106 return "Unknown"; |
1094 } | 1107 } |
1095 | 1108 |
1096 } // namespace blink | 1109 } // namespace blink |
OLD | NEW |