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 | 6 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All |
7 rights reserved. | 7 rights reserved. |
8 | 8 |
9 This library is free software; you can redistribute it and/or | 9 This library is free software; you can redistribute it and/or |
10 modify it under the terms of the GNU Library General Public | 10 modify it under the terms of the GNU Library General Public |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include <cassert> | 29 #include <cassert> |
30 #include <memory> | 30 #include <memory> |
31 #include "platform/Histogram.h" | 31 #include "platform/Histogram.h" |
32 #include "platform/InstanceCounters.h" | 32 #include "platform/InstanceCounters.h" |
33 #include "platform/RuntimeEnabledFeatures.h" | 33 #include "platform/RuntimeEnabledFeatures.h" |
34 #include "platform/SharedBuffer.h" | 34 #include "platform/SharedBuffer.h" |
35 #include "platform/WebTaskRunner.h" | 35 #include "platform/WebTaskRunner.h" |
36 #include "platform/instrumentation/tracing/TraceEvent.h" | 36 #include "platform/instrumentation/tracing/TraceEvent.h" |
37 #include "platform/loader/fetch/CachedMetadata.h" | 37 #include "platform/loader/fetch/CachedMetadata.h" |
38 #include "platform/loader/fetch/CrossOriginAccessControl.h" | 38 #include "platform/loader/fetch/CrossOriginAccessControl.h" |
| 39 #include "platform/loader/fetch/FetchContext.h" |
39 #include "platform/loader/fetch/FetchInitiatorTypeNames.h" | 40 #include "platform/loader/fetch/FetchInitiatorTypeNames.h" |
40 #include "platform/loader/fetch/FetchParameters.h" | 41 #include "platform/loader/fetch/FetchParameters.h" |
41 #include "platform/loader/fetch/IntegrityMetadata.h" | 42 #include "platform/loader/fetch/IntegrityMetadata.h" |
42 #include "platform/loader/fetch/MemoryCache.h" | 43 #include "platform/loader/fetch/MemoryCache.h" |
43 #include "platform/loader/fetch/ResourceClient.h" | 44 #include "platform/loader/fetch/ResourceClient.h" |
44 #include "platform/loader/fetch/ResourceClientWalker.h" | 45 #include "platform/loader/fetch/ResourceClientWalker.h" |
45 #include "platform/loader/fetch/ResourceLoader.h" | 46 #include "platform/loader/fetch/ResourceLoader.h" |
46 #include "platform/network/HTTPParsers.h" | 47 #include "platform/network/HTTPParsers.h" |
47 #include "platform/scheduler/child/web_scheduler.h" | 48 #include "platform/scheduler/child/web_scheduler.h" |
48 #include "platform/weborigin/KURL.h" | 49 #include "platform/weborigin/KURL.h" |
49 #include "platform/wtf/CurrentTime.h" | 50 #include "platform/wtf/CurrentTime.h" |
50 #include "platform/wtf/MathExtras.h" | 51 #include "platform/wtf/MathExtras.h" |
51 #include "platform/wtf/StdLibExtras.h" | 52 #include "platform/wtf/StdLibExtras.h" |
52 #include "platform/wtf/Vector.h" | 53 #include "platform/wtf/Vector.h" |
53 #include "platform/wtf/text/CString.h" | 54 #include "platform/wtf/text/CString.h" |
54 #include "platform/wtf/text/StringBuilder.h" | 55 #include "platform/wtf/text/StringBuilder.h" |
55 #include "public/platform/Platform.h" | 56 #include "public/platform/Platform.h" |
56 #include "public/platform/WebCachePolicy.h" | 57 #include "public/platform/WebCachePolicy.h" |
57 #include "public/platform/WebSecurityOrigin.h" | 58 #include "public/platform/WebSecurityOrigin.h" |
58 | 59 |
59 namespace blink { | 60 namespace blink { |
60 | 61 |
| 62 namespace { |
| 63 |
| 64 class StaticResourceCallback final : public Resource::ResourceCallback { |
| 65 public: |
| 66 StaticResourceCallback(); |
| 67 ~StaticResourceCallback() override; |
| 68 void Schedule(Resource*) override; |
| 69 void Cancel(Resource*) override; |
| 70 bool IsScheduled(Resource*) const override; |
| 71 |
| 72 private: |
| 73 void RunTask(); |
| 74 |
| 75 TaskHandle task_handle_; |
| 76 HashSet<Persistent<Resource>> resources_with_pending_clients_; |
| 77 }; |
| 78 |
| 79 StaticResourceCallback::StaticResourceCallback() {} |
| 80 StaticResourceCallback::~StaticResourceCallback() {} |
| 81 |
| 82 void StaticResourceCallback::Schedule(Resource* resource) { |
| 83 if (!task_handle_.IsActive()) { |
| 84 // WTF::unretained(this) is safe because a posted task is canceled when |
| 85 // |task_handle_| is destroyed on the dtor of this ResourceCallback. |
| 86 task_handle_ = |
| 87 Platform::Current() |
| 88 ->CurrentThread() |
| 89 ->Scheduler() |
| 90 ->LoadingTaskRunner() |
| 91 ->PostCancellableTask(BLINK_FROM_HERE, |
| 92 WTF::Bind(&StaticResourceCallback::RunTask, |
| 93 WTF::Unretained(this))); |
| 94 } |
| 95 resources_with_pending_clients_.insert(resource); |
| 96 } |
| 97 |
| 98 void StaticResourceCallback::Cancel(Resource* resource) { |
| 99 resources_with_pending_clients_.erase(resource); |
| 100 if (task_handle_.IsActive() && resources_with_pending_clients_.IsEmpty()) |
| 101 task_handle_.Cancel(); |
| 102 } |
| 103 |
| 104 bool StaticResourceCallback::IsScheduled(Resource* resource) const { |
| 105 return resources_with_pending_clients_.Contains(resource); |
| 106 } |
| 107 |
| 108 void StaticResourceCallback::RunTask() { |
| 109 HeapVector<Member<Resource>> resources; |
| 110 for (const Member<Resource>& resource : resources_with_pending_clients_) |
| 111 resources.push_back(resource); |
| 112 resources_with_pending_clients_.clear(); |
| 113 |
| 114 for (const auto& resource : resources) |
| 115 resource->FinishPendingClients(); |
| 116 } |
| 117 |
| 118 } // namespace |
| 119 |
61 // These response headers are not copied from a revalidated response to the | 120 // These response headers are not copied from a revalidated response to the |
62 // cached response headers. For compatibility, this list is based on Chromium's | 121 // cached response headers. For compatibility, this list is based on Chromium's |
63 // net/http/http_response_headers.cc. | 122 // net/http/http_response_headers.cc. |
64 const char* const kHeadersToIgnoreAfterRevalidation[] = { | 123 const char* const kHeadersToIgnoreAfterRevalidation[] = { |
65 "allow", | 124 "allow", |
66 "connection", | 125 "connection", |
67 "etag", | 126 "etag", |
68 "expires", | 127 "expires", |
69 "keep-alive", | 128 "keep-alive", |
70 "last-modified", | 129 "last-modified", |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 WebSecurityOrigin(security_origin_), | 298 WebSecurityOrigin(security_origin_), |
240 GetResponse().CacheStorageCacheName()); | 299 GetResponse().CacheStorageCacheName()); |
241 } else { | 300 } else { |
242 Platform::Current()->CacheMetadataInCacheStorage( | 301 Platform::Current()->CacheMetadataInCacheStorage( |
243 GetResponse().Url(), GetResponse().ResponseTime(), nullptr, 0, | 302 GetResponse().Url(), GetResponse().ResponseTime(), nullptr, 0, |
244 WebSecurityOrigin(security_origin_), | 303 WebSecurityOrigin(security_origin_), |
245 GetResponse().CacheStorageCacheName()); | 304 GetResponse().CacheStorageCacheName()); |
246 } | 305 } |
247 } | 306 } |
248 | 307 |
249 // This class cannot be on-heap because the first callbackHandler() call | |
250 // instantiates the singleton object while we can call it in the | |
251 // pre-finalization step. | |
252 class Resource::ResourceCallback final { | |
253 public: | |
254 static ResourceCallback& CallbackHandler(); | |
255 void Schedule(Resource*); | |
256 void Cancel(Resource*); | |
257 bool IsScheduled(Resource*) const; | |
258 | |
259 private: | |
260 ResourceCallback(); | |
261 | |
262 void RunTask(); | |
263 TaskHandle task_handle_; | |
264 HashSet<Persistent<Resource>> resources_with_pending_clients_; | |
265 }; | |
266 | |
267 Resource::ResourceCallback& Resource::ResourceCallback::CallbackHandler() { | |
268 DEFINE_STATIC_LOCAL(ResourceCallback, callback_handler, ()); | |
269 return callback_handler; | |
270 } | |
271 | |
272 Resource::ResourceCallback::ResourceCallback() {} | |
273 | |
274 void Resource::ResourceCallback::Schedule(Resource* resource) { | |
275 if (!task_handle_.IsActive()) { | |
276 // WTF::unretained(this) is safe because a posted task is canceled when | |
277 // |m_taskHandle| is destroyed on the dtor of this ResourceCallback. | |
278 task_handle_ = | |
279 Platform::Current() | |
280 ->CurrentThread() | |
281 ->Scheduler() | |
282 ->LoadingTaskRunner() | |
283 ->PostCancellableTask( | |
284 BLINK_FROM_HERE, | |
285 WTF::Bind(&ResourceCallback::RunTask, WTF::Unretained(this))); | |
286 } | |
287 resources_with_pending_clients_.insert(resource); | |
288 } | |
289 | |
290 void Resource::ResourceCallback::Cancel(Resource* resource) { | |
291 resources_with_pending_clients_.erase(resource); | |
292 if (task_handle_.IsActive() && resources_with_pending_clients_.IsEmpty()) | |
293 task_handle_.Cancel(); | |
294 } | |
295 | |
296 bool Resource::ResourceCallback::IsScheduled(Resource* resource) const { | |
297 return resources_with_pending_clients_.Contains(resource); | |
298 } | |
299 | |
300 void Resource::ResourceCallback::RunTask() { | |
301 HeapVector<Member<Resource>> resources; | |
302 for (const Member<Resource>& resource : resources_with_pending_clients_) | |
303 resources.push_back(resource.Get()); | |
304 resources_with_pending_clients_.clear(); | |
305 | |
306 for (const auto& resource : resources) | |
307 resource->FinishPendingClients(); | |
308 } | |
309 | |
310 Resource::Resource(const ResourceRequest& request, | 308 Resource::Resource(const ResourceRequest& request, |
311 Type type, | 309 Type type, |
312 const ResourceLoaderOptions& options) | 310 const ResourceLoaderOptions& options, |
| 311 FetchContext* fetch_context) |
313 : load_finish_time_(0), | 312 : load_finish_time_(0), |
314 identifier_(0), | 313 identifier_(0), |
315 encoded_size_(0), | 314 encoded_size_(0), |
316 encoded_size_memory_usage_(0), | 315 encoded_size_memory_usage_(0), |
317 decoded_size_(0), | 316 decoded_size_(0), |
318 overhead_size_(CalculateOverheadSize()), | 317 overhead_size_(CalculateOverheadSize()), |
319 preload_count_(0), | 318 preload_count_(0), |
320 preload_discovery_time_(0.0), | 319 preload_discovery_time_(0.0), |
321 cache_identifier_(MemoryCache::DefaultCacheIdentifier()), | 320 cache_identifier_(MemoryCache::DefaultCacheIdentifier()), |
322 preload_result_(kPreloadNotReferenced), | 321 preload_result_(kPreloadNotReferenced), |
323 type_(type), | 322 type_(type), |
324 status_(ResourceStatus::kNotStarted), | 323 status_(ResourceStatus::kNotStarted), |
325 needs_synchronous_cache_hit_(false), | 324 needs_synchronous_cache_hit_(false), |
326 link_preload_(false), | 325 link_preload_(false), |
327 is_revalidating_(false), | 326 is_revalidating_(false), |
328 is_alive_(false), | 327 is_alive_(false), |
329 is_add_remove_client_prohibited_(false), | 328 is_add_remove_client_prohibited_(false), |
330 integrity_disposition_(ResourceIntegrityDisposition::kNotChecked), | 329 integrity_disposition_(ResourceIntegrityDisposition::kNotChecked), |
331 options_(options), | 330 options_(options), |
332 response_timestamp_(CurrentTime()), | 331 response_timestamp_(CurrentTime()), |
333 cancel_timer_(Platform::Current()->MainThread()->GetWebTaskRunner(), | 332 cancel_timer_(fetch_context && fetch_context->TimerTaskRunner() |
| 333 ? fetch_context->TimerTaskRunner() |
| 334 : Platform::Current()->MainThread()->GetWebTaskRunner(), |
334 this, | 335 this, |
335 &Resource::CancelTimerFired), | 336 &Resource::CancelTimerFired), |
| 337 fetch_context_(fetch_context), |
336 resource_request_(request) { | 338 resource_request_(request) { |
337 InstanceCounters::IncrementCounter(InstanceCounters::kResourceCounter); | 339 InstanceCounters::IncrementCounter(InstanceCounters::kResourceCounter); |
338 | 340 |
339 // Currently we support the metadata caching only for HTTP family. | 341 // Currently we support the metadata caching only for HTTP family. |
340 if (GetResourceRequest().Url().ProtocolIsInHTTPFamily()) | 342 if (GetResourceRequest().Url().ProtocolIsInHTTPFamily()) |
341 cache_handler_ = CachedMetadataHandlerImpl::Create(this); | 343 cache_handler_ = CachedMetadataHandlerImpl::Create(this); |
342 MemoryCoordinator::Instance().RegisterClient(this); | 344 if (IsMainThread()) |
| 345 MemoryCoordinator::Instance().RegisterClient(this); |
343 } | 346 } |
344 | 347 |
345 Resource::~Resource() { | 348 Resource::~Resource() { |
346 InstanceCounters::DecrementCounter(InstanceCounters::kResourceCounter); | 349 InstanceCounters::DecrementCounter(InstanceCounters::kResourceCounter); |
347 } | 350 } |
348 | 351 |
349 DEFINE_TRACE(Resource) { | 352 DEFINE_TRACE(Resource) { |
350 visitor->Trace(loader_); | 353 visitor->Trace(loader_); |
| 354 visitor->Trace(fetch_context_); |
351 visitor->Trace(cache_handler_); | 355 visitor->Trace(cache_handler_); |
352 visitor->Trace(clients_); | 356 visitor->Trace(clients_); |
353 visitor->Trace(clients_awaiting_callback_); | 357 visitor->Trace(clients_awaiting_callback_); |
354 visitor->Trace(finished_clients_); | 358 visitor->Trace(finished_clients_); |
355 MemoryCoordinatorClient::Trace(visitor); | 359 MemoryCoordinatorClient::Trace(visitor); |
356 } | 360 } |
357 | 361 |
358 void Resource::SetLoader(ResourceLoader* loader) { | 362 void Resource::SetLoader(ResourceLoader* loader) { |
359 CHECK(!loader_); | 363 CHECK(!loader_); |
360 DCHECK(StillNeedsLoad()); | 364 DCHECK(StillNeedsLoad()); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 options_.data_buffering_policy = data_buffering_policy; | 415 options_.data_buffering_policy = data_buffering_policy; |
412 ClearData(); | 416 ClearData(); |
413 SetEncodedSize(0); | 417 SetEncodedSize(0); |
414 } | 418 } |
415 | 419 |
416 void Resource::GetError(const ResourceError& error) { | 420 void Resource::GetError(const ResourceError& error) { |
417 DCHECK(!error.IsNull()); | 421 DCHECK(!error.IsNull()); |
418 error_ = error; | 422 error_ = error; |
419 is_revalidating_ = false; | 423 is_revalidating_ = false; |
420 | 424 |
421 if (error_.IsCancellation() || !IsPreloaded()) | 425 if ((error_.IsCancellation() || !IsPreloaded()) && IsMainThread()) |
422 GetMemoryCache()->Remove(this); | 426 GetMemoryCache()->Remove(this); |
423 | 427 |
424 if (!ErrorOccurred()) | 428 if (!ErrorOccurred()) |
425 SetStatus(ResourceStatus::kLoadError); | 429 SetStatus(ResourceStatus::kLoadError); |
426 DCHECK(ErrorOccurred()); | 430 DCHECK(ErrorOccurred()); |
427 ClearData(); | 431 ClearData(); |
428 loader_ = nullptr; | 432 loader_ = nullptr; |
429 CheckNotify(); | 433 CheckNotify(); |
430 } | 434 } |
431 | 435 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 builder.Append(' '); | 644 builder.Append(' '); |
641 builder.Append("m_loader"); | 645 builder.Append("m_loader"); |
642 } | 646 } |
643 if (preload_count_) { | 647 if (preload_count_) { |
644 if (!builder.IsEmpty()) | 648 if (!builder.IsEmpty()) |
645 builder.Append(' '); | 649 builder.Append(' '); |
646 builder.Append("m_preloadCount("); | 650 builder.Append("m_preloadCount("); |
647 builder.AppendNumber(preload_count_); | 651 builder.AppendNumber(preload_count_); |
648 builder.Append(')'); | 652 builder.Append(')'); |
649 } | 653 } |
650 if (GetMemoryCache()->Contains(this)) { | 654 if (IsMainThread() && GetMemoryCache()->Contains(this)) { |
651 if (!builder.IsEmpty()) | 655 if (!builder.IsEmpty()) |
652 builder.Append(' '); | 656 builder.Append(' '); |
653 builder.Append("in_memory_cache"); | 657 builder.Append("in_memory_cache"); |
654 } | 658 } |
655 return builder.ToString(); | 659 return builder.ToString(); |
656 } | 660 } |
657 | 661 |
658 void Resource::DidAddClient(ResourceClient* c) { | 662 void Resource::DidAddClient(ResourceClient* c) { |
659 if (IsLoaded()) { | 663 if (IsLoaded()) { |
660 c->NotifyFinished(this); | 664 c->NotifyFinished(this); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 clients_.insert(client); | 719 clients_.insert(client); |
716 return; | 720 return; |
717 } | 721 } |
718 | 722 |
719 // If an error has occurred or we have existing data to send to the new client | 723 // If an error has occurred or we have existing data to send to the new client |
720 // and the resource type supprts it, send it asynchronously. | 724 // and the resource type supprts it, send it asynchronously. |
721 if ((ErrorOccurred() || !GetResponse().IsNull()) && | 725 if ((ErrorOccurred() || !GetResponse().IsNull()) && |
722 !TypeNeedsSynchronousCacheHit(GetType()) && | 726 !TypeNeedsSynchronousCacheHit(GetType()) && |
723 !needs_synchronous_cache_hit_) { | 727 !needs_synchronous_cache_hit_) { |
724 clients_awaiting_callback_.insert(client); | 728 clients_awaiting_callback_.insert(client); |
725 ResourceCallback::CallbackHandler().Schedule(this); | 729 GetResourceCallback().Schedule(this); |
726 return; | 730 return; |
727 } | 731 } |
728 | 732 |
729 clients_.insert(client); | 733 clients_.insert(client); |
730 DidAddClient(client); | 734 DidAddClient(client); |
731 return; | 735 return; |
732 } | 736 } |
733 | 737 |
734 void Resource::RemoveClient(ResourceClient* client) { | 738 void Resource::RemoveClient(ResourceClient* client) { |
735 CHECK(!is_add_remove_client_prohibited_); | 739 CHECK(!is_add_remove_client_prohibited_); |
736 | 740 |
737 // This code may be called in a pre-finalizer, where weak members in the | 741 // This code may be called in a pre-finalizer, where weak members in the |
738 // HashCountedSet are already swept out. | 742 // HashCountedSet are already swept out. |
739 | 743 |
740 if (finished_clients_.Contains(client)) | 744 if (finished_clients_.Contains(client)) |
741 finished_clients_.erase(client); | 745 finished_clients_.erase(client); |
742 else if (clients_awaiting_callback_.Contains(client)) | 746 else if (clients_awaiting_callback_.Contains(client)) |
743 clients_awaiting_callback_.erase(client); | 747 clients_awaiting_callback_.erase(client); |
744 else | 748 else |
745 clients_.erase(client); | 749 clients_.erase(client); |
746 | 750 |
747 if (clients_awaiting_callback_.IsEmpty()) | 751 if (clients_awaiting_callback_.IsEmpty()) |
748 ResourceCallback::CallbackHandler().Cancel(this); | 752 GetResourceCallback().Cancel(this); |
749 | 753 |
750 DidRemoveClientOrObserver(); | 754 DidRemoveClientOrObserver(); |
751 } | 755 } |
752 | 756 |
753 void Resource::DidRemoveClientOrObserver() { | 757 void Resource::DidRemoveClientOrObserver() { |
754 if (!HasClientsOrObservers() && is_alive_) { | 758 if (!HasClientsOrObservers() && is_alive_) { |
755 is_alive_ = false; | 759 is_alive_ = false; |
756 AllClientsAndObserversRemoved(); | 760 AllClientsAndObserversRemoved(); |
757 | 761 |
758 // RFC2616 14.9.2: | 762 // RFC2616 14.9.2: |
759 // "no-store: ... MUST make a best-effort attempt to remove the information | 763 // "no-store: ... MUST make a best-effort attempt to remove the information |
760 // from volatile storage as promptly as possible" | 764 // from volatile storage as promptly as possible" |
761 // "... History buffers MAY store such responses as part of their normal | 765 // "... History buffers MAY store such responses as part of their normal |
762 // operation." | 766 // operation." |
763 // We allow non-secure content to be reused in history, but we do not allow | 767 // We allow non-secure content to be reused in history, but we do not allow |
764 // secure content to be reused. | 768 // secure content to be reused. |
765 if (HasCacheControlNoStoreHeader() && Url().ProtocolIs("https")) | 769 if (HasCacheControlNoStoreHeader() && Url().ProtocolIs("https") && |
| 770 IsMainThread()) |
766 GetMemoryCache()->Remove(this); | 771 GetMemoryCache()->Remove(this); |
767 } | 772 } |
768 } | 773 } |
769 | 774 |
770 void Resource::AllClientsAndObserversRemoved() { | 775 void Resource::AllClientsAndObserversRemoved() { |
771 if (!loader_) | 776 if (!loader_) |
772 return; | 777 return; |
773 if (!cancel_timer_.IsActive()) | 778 if (!cancel_timer_.IsActive()) |
774 cancel_timer_.StartOneShot(0, BLINK_FROM_HERE); | 779 cancel_timer_.StartOneShot(0, BLINK_FROM_HERE); |
775 } | 780 } |
776 | 781 |
777 void Resource::CancelTimerFired(TimerBase* timer) { | 782 void Resource::CancelTimerFired(TimerBase* timer) { |
778 DCHECK_EQ(timer, &cancel_timer_); | 783 DCHECK_EQ(timer, &cancel_timer_); |
779 if (!HasClientsOrObservers() && loader_) | 784 if (!HasClientsOrObservers() && loader_) |
780 loader_->Cancel(); | 785 loader_->Cancel(); |
781 } | 786 } |
782 | 787 |
783 void Resource::SetDecodedSize(size_t decoded_size) { | 788 void Resource::SetDecodedSize(size_t decoded_size) { |
784 if (decoded_size == decoded_size_) | 789 if (decoded_size == decoded_size_) |
785 return; | 790 return; |
786 size_t old_size = size(); | 791 size_t old_size = size(); |
787 decoded_size_ = decoded_size; | 792 decoded_size_ = decoded_size; |
788 GetMemoryCache()->Update(this, old_size, size()); | 793 if (IsMainThread()) |
| 794 GetMemoryCache()->Update(this, old_size, size()); |
789 } | 795 } |
790 | 796 |
791 void Resource::SetEncodedSize(size_t encoded_size) { | 797 void Resource::SetEncodedSize(size_t encoded_size) { |
792 if (encoded_size == encoded_size_ && | 798 if (encoded_size == encoded_size_ && |
793 encoded_size == encoded_size_memory_usage_) | 799 encoded_size == encoded_size_memory_usage_) |
794 return; | 800 return; |
795 size_t old_size = size(); | 801 size_t old_size = size(); |
796 encoded_size_ = encoded_size; | 802 encoded_size_ = encoded_size; |
797 encoded_size_memory_usage_ = encoded_size; | 803 encoded_size_memory_usage_ = encoded_size; |
798 GetMemoryCache()->Update(this, old_size, size()); | 804 if (IsMainThread()) |
| 805 GetMemoryCache()->Update(this, old_size, size()); |
799 } | 806 } |
800 | 807 |
801 void Resource::FinishPendingClients() { | 808 void Resource::FinishPendingClients() { |
802 // We're going to notify clients one by one. It is simple if the client does | 809 // We're going to notify clients one by one. It is simple if the client does |
803 // nothing. However there are a couple other things that can happen. | 810 // nothing. However there are a couple other things that can happen. |
804 // | 811 // |
805 // 1. Clients can be added during the loop. Make sure they are not processed. | 812 // 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 | 813 // 2. Clients can be removed during the loop. Make sure they are always |
807 // available to be removed. Also don't call removed clients or add them | 814 // available to be removed. Also don't call removed clients or add them |
808 // back. | 815 // back. |
(...skipping 11 matching lines...) Expand all Loading... |
820 | 827 |
821 // When revalidation starts after waiting clients are scheduled and | 828 // When revalidation starts after waiting clients are scheduled and |
822 // before they are added here. In such cases, we just add the clients | 829 // before they are added here. In such cases, we just add the clients |
823 // to |m_clients| without didAddClient(), as in Resource::addClient(). | 830 // to |m_clients| without didAddClient(), as in Resource::addClient(). |
824 if (!is_revalidating_) | 831 if (!is_revalidating_) |
825 DidAddClient(client); | 832 DidAddClient(client); |
826 } | 833 } |
827 | 834 |
828 // It is still possible for the above loop to finish a new client | 835 // It is still possible for the above loop to finish a new client |
829 // synchronously. If there's no client waiting we should deschedule. | 836 // synchronously. If there's no client waiting we should deschedule. |
830 bool scheduled = ResourceCallback::CallbackHandler().IsScheduled(this); | 837 bool scheduled = GetResourceCallback().IsScheduled(this); |
831 if (scheduled && clients_awaiting_callback_.IsEmpty()) | 838 if (scheduled && clients_awaiting_callback_.IsEmpty()) |
832 ResourceCallback::CallbackHandler().Cancel(this); | 839 GetResourceCallback().Cancel(this); |
833 | 840 |
834 // Prevent the case when there are clients waiting but no callback scheduled. | 841 // Prevent the case when there are clients waiting but no callback scheduled. |
835 DCHECK(clients_awaiting_callback_.IsEmpty() || scheduled); | 842 DCHECK(clients_awaiting_callback_.IsEmpty() || scheduled); |
836 } | 843 } |
837 | 844 |
838 void Resource::Prune() { | 845 void Resource::Prune() { |
839 DestroyDecodedDataIfPossible(); | 846 DestroyDecodedDataIfPossible(); |
840 } | 847 } |
841 | 848 |
842 void Resource::OnPurgeMemory() { | 849 void Resource::OnPurgeMemory() { |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 case Resource::kTextTrack: | 1126 case Resource::kTextTrack: |
1120 case Resource::kMedia: | 1127 case Resource::kMedia: |
1121 case Resource::kManifest: | 1128 case Resource::kManifest: |
1122 case Resource::kMock: | 1129 case Resource::kMock: |
1123 return false; | 1130 return false; |
1124 } | 1131 } |
1125 NOTREACHED(); | 1132 NOTREACHED(); |
1126 return false; | 1133 return false; |
1127 } | 1134 } |
1128 | 1135 |
| 1136 Resource::ResourceCallback& Resource::GetResourceCallback() { |
| 1137 if (fetch_context_ && fetch_context_->GetResourceCallback()) { |
| 1138 DCHECK(!IsMainThread()); |
| 1139 return *fetch_context_->GetResourceCallback(); |
| 1140 } |
| 1141 DCHECK(IsMainThread()); |
| 1142 DEFINE_STATIC_LOCAL(StaticResourceCallback, callback_handler, ()); |
| 1143 return callback_handler; |
| 1144 } |
| 1145 |
1129 } // namespace blink | 1146 } // namespace blink |
OLD | NEW |