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 | |
214 Resource::Resource(const ResourceRequest& request, Type type, const ResourceLoad
erOptions& options) | 147 Resource::Resource(const ResourceRequest& request, Type type, const ResourceLoad
erOptions& options) |
215 : m_resourceRequest(request) | 148 : m_resourceRequest(request) |
216 , m_options(options) | 149 , m_options(options) |
217 , m_responseTimestamp(currentTime()) | 150 , m_responseTimestamp(currentTime()) |
218 , m_cancelTimer(this, &Resource::cancelTimerFired) | 151 , m_cancelTimer(this, &Resource::cancelTimerFired) |
219 #if !ENABLE(OILPAN) | 152 #if !ENABLE(OILPAN) |
220 , m_weakPtrFactory(this) | 153 , m_weakPtrFactory(this) |
221 #endif | 154 #endif |
222 , m_loadFinishTime(0) | 155 , m_loadFinishTime(0) |
223 , m_identifier(0) | 156 , m_identifier(0) |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 willAddClientOrObserver(); | 602 willAddClientOrObserver(); |
670 | 603 |
671 if (!m_revalidatingRequest.isNull()) { | 604 if (!m_revalidatingRequest.isNull()) { |
672 m_clients.add(client); | 605 m_clients.add(client); |
673 return; | 606 return; |
674 } | 607 } |
675 | 608 |
676 // If we have existing data to send to the new client and the resource type
supprts it, send it asynchronously. | 609 // If we have existing data to send to the new client and the resource type
supprts it, send it asynchronously. |
677 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(getTyp
e()) && !m_needsSynchronousCacheHit) { | 610 if (!m_response.isNull() && !shouldSendCachedDataSynchronouslyForType(getTyp
e()) && !m_needsSynchronousCacheHit) { |
678 m_clientsAwaitingCallback.add(client); | 611 m_clientsAwaitingCallback.add(client); |
679 ResourceCallback::callbackHandler().schedule(this); | 612 ResourceCallback::callbackHandler()->schedule(this); |
680 return; | 613 return; |
681 } | 614 } |
682 | 615 |
683 m_clients.add(client); | 616 m_clients.add(client); |
684 didAddClient(client); | 617 didAddClient(client); |
685 return; | 618 return; |
686 } | 619 } |
687 | 620 |
688 void Resource::removeClient(ResourceClient* client) | 621 void Resource::removeClient(ResourceClient* client) |
689 { | 622 { |
690 ASSERT(hasClient(client)); | 623 ASSERT(hasClient(client)); |
691 if (m_finishedClients.contains(client)) | 624 if (m_finishedClients.contains(client)) |
692 m_finishedClients.remove(client); | 625 m_finishedClients.remove(client); |
693 else if (m_clientsAwaitingCallback.contains(client)) | 626 else if (m_clientsAwaitingCallback.contains(client)) |
694 m_clientsAwaitingCallback.remove(client); | 627 m_clientsAwaitingCallback.remove(client); |
695 else | 628 else |
696 m_clients.remove(client); | 629 m_clients.remove(client); |
697 | 630 |
698 if (m_clientsAwaitingCallback.isEmpty()) | 631 if (m_clientsAwaitingCallback.isEmpty()) |
699 ResourceCallback::callbackHandler().cancel(this); | 632 ResourceCallback::callbackHandler()->cancel(this); |
700 | 633 |
701 didRemoveClientOrObserver(); | 634 didRemoveClientOrObserver(); |
702 // This object may be dead here. | 635 // This object may be dead here. |
703 } | 636 } |
704 | 637 |
705 void Resource::didRemoveClientOrObserver() | 638 void Resource::didRemoveClientOrObserver() |
706 { | 639 { |
707 if (!hasClientsOrObservers()) { | 640 if (!hasClientsOrObservers()) { |
708 RawPtr<Resource> protect(this); | 641 RawPtr<Resource> protect(this); |
709 memoryCache()->makeDead(this); | 642 memoryCache()->makeDead(this); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 for (const auto& client : clientsToNotify) { | 720 for (const auto& client : clientsToNotify) { |
788 // Handle case (2) to skip removed clients. | 721 // Handle case (2) to skip removed clients. |
789 if (!m_clientsAwaitingCallback.remove(client)) | 722 if (!m_clientsAwaitingCallback.remove(client)) |
790 continue; | 723 continue; |
791 m_clients.add(client); | 724 m_clients.add(client); |
792 didAddClient(client); | 725 didAddClient(client); |
793 } | 726 } |
794 | 727 |
795 // It is still possible for the above loop to finish a new client synchronou
sly. | 728 // It is still possible for the above loop to finish a new client synchronou
sly. |
796 // If there's no client waiting we should deschedule. | 729 // If there's no client waiting we should deschedule. |
797 bool scheduled = ResourceCallback::callbackHandler().isScheduled(this); | 730 bool scheduled = ResourceCallback::callbackHandler()->isScheduled(this); |
798 if (scheduled && m_clientsAwaitingCallback.isEmpty()) | 731 if (scheduled && m_clientsAwaitingCallback.isEmpty()) |
799 ResourceCallback::callbackHandler().cancel(this); | 732 ResourceCallback::callbackHandler()->cancel(this); |
800 | 733 |
801 // Prevent the case when there are clients waiting but no callback scheduled
. | 734 // Prevent the case when there are clients waiting but no callback scheduled
. |
802 ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled); | 735 ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled); |
803 } | 736 } |
804 | 737 |
805 void Resource::prune() | 738 void Resource::prune() |
806 { | 739 { |
807 destroyDecodedDataIfPossible(); | 740 destroyDecodedDataIfPossible(); |
808 unlock(); | 741 unlock(); |
809 } | 742 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 return sizeof(Resource) + m_response.memoryUsage() + kAverageClientsHashMapS
ize + m_resourceRequest.url().getString().length() * 2; | 905 return sizeof(Resource) + m_response.memoryUsage() + kAverageClientsHashMapS
ize + m_resourceRequest.url().getString().length() * 2; |
973 } | 906 } |
974 | 907 |
975 void Resource::didChangePriority(ResourceLoadPriority loadPriority, int intraPri
orityValue) | 908 void Resource::didChangePriority(ResourceLoadPriority loadPriority, int intraPri
orityValue) |
976 { | 909 { |
977 m_resourceRequest.setPriority(loadPriority, intraPriorityValue); | 910 m_resourceRequest.setPriority(loadPriority, intraPriorityValue); |
978 if (m_loader) | 911 if (m_loader) |
979 m_loader->didChangePriority(loadPriority, intraPriorityValue); | 912 m_loader->didChangePriority(loadPriority, intraPriorityValue); |
980 } | 913 } |
981 | 914 |
| 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 |
982 static const char* initatorTypeNameToString(const AtomicString& initiatorTypeNam
e) | 969 static const char* initatorTypeNameToString(const AtomicString& initiatorTypeNam
e) |
983 { | 970 { |
984 if (initiatorTypeName == FetchInitiatorTypeNames::css) | 971 if (initiatorTypeName == FetchInitiatorTypeNames::css) |
985 return "CSS resource"; | 972 return "CSS resource"; |
986 if (initiatorTypeName == FetchInitiatorTypeNames::document) | 973 if (initiatorTypeName == FetchInitiatorTypeNames::document) |
987 return "Document"; | 974 return "Document"; |
988 if (initiatorTypeName == FetchInitiatorTypeNames::icon) | 975 if (initiatorTypeName == FetchInitiatorTypeNames::icon) |
989 return "Icon"; | 976 return "Icon"; |
990 if (initiatorTypeName == FetchInitiatorTypeNames::internal) | 977 if (initiatorTypeName == FetchInitiatorTypeNames::internal) |
991 return "Internal resource"; | 978 return "Internal resource"; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1100 case Resource::Media: | 1087 case Resource::Media: |
1101 return "Media"; | 1088 return "Media"; |
1102 case Resource::Manifest: | 1089 case Resource::Manifest: |
1103 return "Manifest"; | 1090 return "Manifest"; |
1104 } | 1091 } |
1105 ASSERT_NOT_REACHED(); | 1092 ASSERT_NOT_REACHED(); |
1106 return "Unknown"; | 1093 return "Unknown"; |
1107 } | 1094 } |
1108 | 1095 |
1109 } // namespace blink | 1096 } // namespace blink |
OLD | NEW |