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/weborigin/KURL.h" | 48 #include "platform/weborigin/KURL.h" |
48 #include "platform/wtf/CurrentTime.h" | 49 #include "platform/wtf/CurrentTime.h" |
49 #include "platform/wtf/MathExtras.h" | 50 #include "platform/wtf/MathExtras.h" |
50 #include "platform/wtf/StdLibExtras.h" | 51 #include "platform/wtf/StdLibExtras.h" |
51 #include "platform/wtf/Vector.h" | 52 #include "platform/wtf/Vector.h" |
52 #include "platform/wtf/text/CString.h" | 53 #include "platform/wtf/text/CString.h" |
53 #include "platform/wtf/text/StringBuilder.h" | 54 #include "platform/wtf/text/StringBuilder.h" |
54 #include "public/platform/Platform.h" | 55 #include "public/platform/Platform.h" |
55 #include "public/platform/WebCachePolicy.h" | 56 #include "public/platform/WebCachePolicy.h" |
56 #include "public/platform/WebScheduler.h" | 57 #include "public/platform/WebScheduler.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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 builder.Append(' '); | 652 builder.Append(' '); |
649 builder.Append("m_loader"); | 653 builder.Append("m_loader"); |
650 } | 654 } |
651 if (preload_count_) { | 655 if (preload_count_) { |
652 if (!builder.IsEmpty()) | 656 if (!builder.IsEmpty()) |
653 builder.Append(' '); | 657 builder.Append(' '); |
654 builder.Append("m_preloadCount("); | 658 builder.Append("m_preloadCount("); |
655 builder.AppendNumber(preload_count_); | 659 builder.AppendNumber(preload_count_); |
656 builder.Append(')'); | 660 builder.Append(')'); |
657 } | 661 } |
658 if (GetMemoryCache()->Contains(this)) { | 662 if (IsMainThread() && GetMemoryCache()->Contains(this)) { |
659 if (!builder.IsEmpty()) | 663 if (!builder.IsEmpty()) |
660 builder.Append(' '); | 664 builder.Append(' '); |
661 builder.Append("in_memory_cache"); | 665 builder.Append("in_memory_cache"); |
662 } | 666 } |
663 return builder.ToString(); | 667 return builder.ToString(); |
664 } | 668 } |
665 | 669 |
666 void Resource::DidAddClient(ResourceClient* c) { | 670 void Resource::DidAddClient(ResourceClient* c) { |
667 if (IsLoaded()) { | 671 if (IsLoaded()) { |
668 c->NotifyFinished(this); | 672 c->NotifyFinished(this); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 clients_.insert(client); | 727 clients_.insert(client); |
724 return; | 728 return; |
725 } | 729 } |
726 | 730 |
727 // If an error has occurred or we have existing data to send to the new client | 731 // If an error has occurred or we have existing data to send to the new client |
728 // and the resource type supprts it, send it asynchronously. | 732 // and the resource type supprts it, send it asynchronously. |
729 if ((ErrorOccurred() || !GetResponse().IsNull()) && | 733 if ((ErrorOccurred() || !GetResponse().IsNull()) && |
730 !TypeNeedsSynchronousCacheHit(GetType()) && | 734 !TypeNeedsSynchronousCacheHit(GetType()) && |
731 !needs_synchronous_cache_hit_) { | 735 !needs_synchronous_cache_hit_) { |
732 clients_awaiting_callback_.insert(client); | 736 clients_awaiting_callback_.insert(client); |
733 ResourceCallback::CallbackHandler().Schedule(this); | 737 GetResourceCallback().Schedule(this); |
734 return; | 738 return; |
735 } | 739 } |
736 | 740 |
737 clients_.insert(client); | 741 clients_.insert(client); |
738 DidAddClient(client); | 742 DidAddClient(client); |
739 return; | 743 return; |
740 } | 744 } |
741 | 745 |
742 void Resource::RemoveClient(ResourceClient* client) { | 746 void Resource::RemoveClient(ResourceClient* client) { |
743 CHECK(!is_add_remove_client_prohibited_); | 747 CHECK(!is_add_remove_client_prohibited_); |
744 | 748 |
745 // This code may be called in a pre-finalizer, where weak members in the | 749 // This code may be called in a pre-finalizer, where weak members in the |
746 // HashCountedSet are already swept out. | 750 // HashCountedSet are already swept out. |
747 | 751 |
748 if (finished_clients_.Contains(client)) | 752 if (finished_clients_.Contains(client)) |
749 finished_clients_.erase(client); | 753 finished_clients_.erase(client); |
750 else if (clients_awaiting_callback_.Contains(client)) | 754 else if (clients_awaiting_callback_.Contains(client)) |
751 clients_awaiting_callback_.erase(client); | 755 clients_awaiting_callback_.erase(client); |
752 else | 756 else |
753 clients_.erase(client); | 757 clients_.erase(client); |
754 | 758 |
755 if (clients_awaiting_callback_.IsEmpty()) | 759 if (clients_awaiting_callback_.IsEmpty()) |
756 ResourceCallback::CallbackHandler().Cancel(this); | 760 GetResourceCallback().Cancel(this); |
757 | 761 |
758 DidRemoveClientOrObserver(); | 762 DidRemoveClientOrObserver(); |
759 } | 763 } |
760 | 764 |
761 void Resource::DidRemoveClientOrObserver() { | 765 void Resource::DidRemoveClientOrObserver() { |
762 if (!HasClientsOrObservers() && is_alive_) { | 766 if (!HasClientsOrObservers() && is_alive_) { |
763 is_alive_ = false; | 767 is_alive_ = false; |
764 AllClientsAndObserversRemoved(); | 768 AllClientsAndObserversRemoved(); |
765 | 769 |
766 // RFC2616 14.9.2: | 770 // RFC2616 14.9.2: |
767 // "no-store: ... MUST make a best-effort attempt to remove the information | 771 // "no-store: ... MUST make a best-effort attempt to remove the information |
768 // from volatile storage as promptly as possible" | 772 // from volatile storage as promptly as possible" |
769 // "... History buffers MAY store such responses as part of their normal | 773 // "... History buffers MAY store such responses as part of their normal |
770 // operation." | 774 // operation." |
771 // We allow non-secure content to be reused in history, but we do not allow | 775 // We allow non-secure content to be reused in history, but we do not allow |
772 // secure content to be reused. | 776 // secure content to be reused. |
773 if (HasCacheControlNoStoreHeader() && Url().ProtocolIs("https")) | 777 if (HasCacheControlNoStoreHeader() && Url().ProtocolIs("https") && |
| 778 IsMainThread()) |
774 GetMemoryCache()->Remove(this); | 779 GetMemoryCache()->Remove(this); |
775 } | 780 } |
776 } | 781 } |
777 | 782 |
778 void Resource::AllClientsAndObserversRemoved() { | 783 void Resource::AllClientsAndObserversRemoved() { |
779 if (!loader_) | 784 if (!loader_) |
780 return; | 785 return; |
781 if (!cancel_timer_.IsActive()) | 786 if (!cancel_timer_.IsActive()) |
782 cancel_timer_.StartOneShot(0, BLINK_FROM_HERE); | 787 cancel_timer_.StartOneShot(0, BLINK_FROM_HERE); |
783 } | 788 } |
784 | 789 |
785 void Resource::CancelTimerFired(TimerBase* timer) { | 790 void Resource::CancelTimerFired(TimerBase* timer) { |
786 DCHECK_EQ(timer, &cancel_timer_); | 791 DCHECK_EQ(timer, &cancel_timer_); |
787 if (!HasClientsOrObservers() && loader_) | 792 if (!HasClientsOrObservers() && loader_) |
788 loader_->Cancel(); | 793 loader_->Cancel(); |
789 } | 794 } |
790 | 795 |
791 void Resource::SetDecodedSize(size_t decoded_size) { | 796 void Resource::SetDecodedSize(size_t decoded_size) { |
792 if (decoded_size == decoded_size_) | 797 if (decoded_size == decoded_size_) |
793 return; | 798 return; |
794 size_t old_size = size(); | 799 size_t old_size = size(); |
795 decoded_size_ = decoded_size; | 800 decoded_size_ = decoded_size; |
796 GetMemoryCache()->Update(this, old_size, size()); | 801 if (IsMainThread()) |
| 802 GetMemoryCache()->Update(this, old_size, size()); |
797 } | 803 } |
798 | 804 |
799 void Resource::SetEncodedSize(size_t encoded_size) { | 805 void Resource::SetEncodedSize(size_t encoded_size) { |
800 if (encoded_size == encoded_size_ && | 806 if (encoded_size == encoded_size_ && |
801 encoded_size == encoded_size_memory_usage_) | 807 encoded_size == encoded_size_memory_usage_) |
802 return; | 808 return; |
803 size_t old_size = size(); | 809 size_t old_size = size(); |
804 encoded_size_ = encoded_size; | 810 encoded_size_ = encoded_size; |
805 encoded_size_memory_usage_ = encoded_size; | 811 encoded_size_memory_usage_ = encoded_size; |
806 GetMemoryCache()->Update(this, old_size, size()); | 812 if (IsMainThread()) |
| 813 GetMemoryCache()->Update(this, old_size, size()); |
807 } | 814 } |
808 | 815 |
809 void Resource::FinishPendingClients() { | 816 void Resource::FinishPendingClients() { |
810 // We're going to notify clients one by one. It is simple if the client does | 817 // We're going to notify clients one by one. It is simple if the client does |
811 // nothing. However there are a couple other things that can happen. | 818 // nothing. However there are a couple other things that can happen. |
812 // | 819 // |
813 // 1. Clients can be added during the loop. Make sure they are not processed. | 820 // 1. Clients can be added during the loop. Make sure they are not processed. |
814 // 2. Clients can be removed during the loop. Make sure they are always | 821 // 2. Clients can be removed during the loop. Make sure they are always |
815 // available to be removed. Also don't call removed clients or add them | 822 // available to be removed. Also don't call removed clients or add them |
816 // back. | 823 // back. |
(...skipping 11 matching lines...) Expand all Loading... |
828 | 835 |
829 // When revalidation starts after waiting clients are scheduled and | 836 // When revalidation starts after waiting clients are scheduled and |
830 // before they are added here. In such cases, we just add the clients | 837 // before they are added here. In such cases, we just add the clients |
831 // to |m_clients| without didAddClient(), as in Resource::addClient(). | 838 // to |m_clients| without didAddClient(), as in Resource::addClient(). |
832 if (!is_revalidating_) | 839 if (!is_revalidating_) |
833 DidAddClient(client); | 840 DidAddClient(client); |
834 } | 841 } |
835 | 842 |
836 // It is still possible for the above loop to finish a new client | 843 // It is still possible for the above loop to finish a new client |
837 // synchronously. If there's no client waiting we should deschedule. | 844 // synchronously. If there's no client waiting we should deschedule. |
838 bool scheduled = ResourceCallback::CallbackHandler().IsScheduled(this); | 845 bool scheduled = GetResourceCallback().IsScheduled(this); |
839 if (scheduled && clients_awaiting_callback_.IsEmpty()) | 846 if (scheduled && clients_awaiting_callback_.IsEmpty()) |
840 ResourceCallback::CallbackHandler().Cancel(this); | 847 GetResourceCallback().Cancel(this); |
841 | 848 |
842 // Prevent the case when there are clients waiting but no callback scheduled. | 849 // Prevent the case when there are clients waiting but no callback scheduled. |
843 DCHECK(clients_awaiting_callback_.IsEmpty() || scheduled); | 850 DCHECK(clients_awaiting_callback_.IsEmpty() || scheduled); |
844 } | 851 } |
845 | 852 |
846 void Resource::Prune() { | 853 void Resource::Prune() { |
847 DestroyDecodedDataIfPossible(); | 854 DestroyDecodedDataIfPossible(); |
848 } | 855 } |
849 | 856 |
850 void Resource::OnPurgeMemory() { | 857 void Resource::OnPurgeMemory() { |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1127 case Resource::kTextTrack: | 1134 case Resource::kTextTrack: |
1128 case Resource::kMedia: | 1135 case Resource::kMedia: |
1129 case Resource::kManifest: | 1136 case Resource::kManifest: |
1130 case Resource::kMock: | 1137 case Resource::kMock: |
1131 return false; | 1138 return false; |
1132 } | 1139 } |
1133 NOTREACHED(); | 1140 NOTREACHED(); |
1134 return false; | 1141 return false; |
1135 } | 1142 } |
1136 | 1143 |
| 1144 Resource::ResourceCallback& Resource::GetResourceCallback() { |
| 1145 if (fetch_context_ && fetch_context_->GetResourceCallback()) { |
| 1146 DCHECK(!IsMainThread()); |
| 1147 return *fetch_context_->GetResourceCallback(); |
| 1148 } |
| 1149 DCHECK(IsMainThread()); |
| 1150 DEFINE_STATIC_LOCAL(StaticResourceCallback, callback_handler, ()); |
| 1151 return callback_handler; |
| 1152 } |
| 1153 |
1137 } // namespace blink | 1154 } // namespace blink |
OLD | NEW |