| Index: third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
|
| diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
|
| index 8d71536aec303906ec858150b97177bf42a4e1e3..ac6b15caddff165963fb8dc9a59449105ef3fab3 100644
|
| --- a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
|
| +++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
|
| @@ -246,67 +246,6 @@ void Resource::ServiceWorkerResponseCachedMetadataHandler::SendToPlatform() {
|
| }
|
| }
|
|
|
| -// This class cannot be on-heap because the first callbackHandler() call
|
| -// instantiates the singleton object while we can call it in the
|
| -// pre-finalization step.
|
| -class Resource::ResourceCallback final {
|
| - public:
|
| - static ResourceCallback& CallbackHandler();
|
| - void Schedule(Resource*);
|
| - void Cancel(Resource*);
|
| - bool IsScheduled(Resource*) const;
|
| -
|
| - private:
|
| - ResourceCallback();
|
| -
|
| - void RunTask();
|
| - TaskHandle task_handle_;
|
| - HashSet<Persistent<Resource>> resources_with_pending_clients_;
|
| -};
|
| -
|
| -Resource::ResourceCallback& Resource::ResourceCallback::CallbackHandler() {
|
| - DEFINE_STATIC_LOCAL(ResourceCallback, callback_handler, ());
|
| - return callback_handler;
|
| -}
|
| -
|
| -Resource::ResourceCallback::ResourceCallback() {}
|
| -
|
| -void Resource::ResourceCallback::Schedule(Resource* resource) {
|
| - if (!task_handle_.IsActive()) {
|
| - // WTF::unretained(this) is safe because a posted task is canceled when
|
| - // |task_handle_| is destroyed on the dtor of this ResourceCallback.
|
| - task_handle_ =
|
| - Platform::Current()
|
| - ->CurrentThread()
|
| - ->Scheduler()
|
| - ->LoadingTaskRunner()
|
| - ->PostCancellableTask(
|
| - BLINK_FROM_HERE,
|
| - WTF::Bind(&ResourceCallback::RunTask, WTF::Unretained(this)));
|
| - }
|
| - resources_with_pending_clients_.insert(resource);
|
| -}
|
| -
|
| -void Resource::ResourceCallback::Cancel(Resource* resource) {
|
| - resources_with_pending_clients_.erase(resource);
|
| - if (task_handle_.IsActive() && resources_with_pending_clients_.IsEmpty())
|
| - task_handle_.Cancel();
|
| -}
|
| -
|
| -bool Resource::ResourceCallback::IsScheduled(Resource* resource) const {
|
| - return resources_with_pending_clients_.Contains(resource);
|
| -}
|
| -
|
| -void Resource::ResourceCallback::RunTask() {
|
| - HeapVector<Member<Resource>> resources;
|
| - for (const Member<Resource>& resource : resources_with_pending_clients_)
|
| - resources.push_back(resource.Get());
|
| - resources_with_pending_clients_.clear();
|
| -
|
| - for (const auto& resource : resources)
|
| - resource->FinishPendingClients();
|
| -}
|
| -
|
| Resource::Resource(const ResourceRequest& request,
|
| Type type,
|
| const ResourceLoaderOptions& options)
|
| @@ -722,7 +661,16 @@ void Resource::AddClient(ResourceClient* client,
|
| !TypeNeedsSynchronousCacheHit(GetType()) &&
|
| !needs_synchronous_cache_hit_) {
|
| clients_awaiting_callback_.insert(client);
|
| - ResourceCallback::CallbackHandler().Schedule(this);
|
| + if (!async_finish_pending_clients_task_.IsActive()) {
|
| + async_finish_pending_clients_task_ =
|
| + Platform::Current()
|
| + ->CurrentThread()
|
| + ->Scheduler()
|
| + ->LoadingTaskRunner()
|
| + ->PostCancellableTask(BLINK_FROM_HERE,
|
| + WTF::Bind(&Resource::FinishPendingClients,
|
| + WrapWeakPersistent(this)));
|
| + }
|
| return;
|
| }
|
|
|
| @@ -744,8 +692,10 @@ void Resource::RemoveClient(ResourceClient* client) {
|
| else
|
| clients_.erase(client);
|
|
|
| - if (clients_awaiting_callback_.IsEmpty())
|
| - ResourceCallback::CallbackHandler().Cancel(this);
|
| + if (clients_awaiting_callback_.IsEmpty() &&
|
| + async_finish_pending_clients_task_.IsActive()) {
|
| + async_finish_pending_clients_task_.Cancel();
|
| + }
|
|
|
| DidRemoveClientOrObserver();
|
| }
|
| @@ -827,9 +777,9 @@ void Resource::FinishPendingClients() {
|
|
|
| // It is still possible for the above loop to finish a new client
|
| // synchronously. If there's no client waiting we should deschedule.
|
| - bool scheduled = ResourceCallback::CallbackHandler().IsScheduled(this);
|
| + bool scheduled = async_finish_pending_clients_task_.IsActive();
|
| if (scheduled && clients_awaiting_callback_.IsEmpty())
|
| - ResourceCallback::CallbackHandler().Cancel(this);
|
| + async_finish_pending_clients_task_.Cancel();
|
|
|
| // Prevent the case when there are clients waiting but no callback scheduled.
|
| DCHECK(clients_awaiting_callback_.IsEmpty() || scheduled);
|
|
|