Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: third_party/WebKit/Source/core/fetch/Resource.cpp

Issue 1850413002: Improve DEFINE_STATIC_LOCAL()'s handling of Blink GCed objects. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address compilation failure Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/fetch/Resource.h ('k') | third_party/WebKit/Source/core/frame/Frame.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698