diff options
author | ddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-04 16:19:14 +0000 |
---|---|---|
committer | ddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-04 16:19:14 +0000 |
commit | 80c71de2dbd4ee5fd78a598b06daffacf3a35a7f (patch) | |
tree | 1eecec7747a9179a56b072365fac697214e699ef | |
parent | 8f7320ed810cf0409aadae175d42463fdaebe1ab (diff) | |
download | chromium_src-80c71de2dbd4ee5fd78a598b06daffacf3a35a7f.zip chromium_src-80c71de2dbd4ee5fd78a598b06daffacf3a35a7f.tar.gz chromium_src-80c71de2dbd4ee5fd78a598b06daffacf3a35a7f.tar.bz2 |
Defer asynchronous loading when the buffer in PPB_URLLoader_Impl exceeds an optionally-specified threshold and re-enable it when the buffer drops below a lower threshold.
BUG=80684
TEST=Set the thresholds to 4 MB and 2 MB, respectively from a plugin then download a large file (> 200 MB). Observe that the renderer/plugin process memory usage in Task Manager does not exceed ~100MB and that network traffic drops to 0 then picks up again briefly after 10 MB are used.
Review URL: http://codereview.chromium.org/6923002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84071 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ppapi/c/ppb_url_request_info.h | 29 | ||||
-rw-r--r-- | ppapi/cpp/url_request_info.h | 8 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_url_loader_impl.cc | 32 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_url_loader_impl.h | 2 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_url_request_info_impl.cc | 25 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_url_request_info_impl.h | 12 |
6 files changed, 106 insertions, 2 deletions
diff --git a/ppapi/c/ppb_url_request_info.h b/ppapi/c/ppb_url_request_info.h index b577376..dea3ee7 100644 --- a/ppapi/c/ppb_url_request_info.h +++ b/ppapi/c/ppb_url_request_info.h @@ -117,7 +117,34 @@ typedef enum { * custom content transfer encoding; if given to a loader without universal * access, PP_ERROR_BADARGUMENT will result. */ - PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING + PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING, + + /** + * This corresponds to an integer (PP_VARTYPE_INT32); default is not defined + * and is set by the browser, possibly depending on system capabilities. + * Set it to an integer to set an upper threshold for the prefetched buffer + * of an asynchronous load. When exceeded, the browser will defer loading + * until PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERERTHRESHOLD is hit, at which + * time it will begin prefetching again. + * When setting this property, + * PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERERTHRESHOLD must also be set. + * Behavior is undefined if the former is <= the latter. + */ + PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD, + + /** + * This corresponds to an integer (PP_VARTYPE_INT32); default is not defined + * and is set by the browser to a value appropriate for the default + * PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD. + * Set it to an integer to set a lower threshold for the prefetched buffer + * of an asynchronous load. When reached, the browser will resume loading if + * If PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERERTHRESHOLD had previously been + * reached. + * When setting this property, + * PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD must also be set. + * Behavior is undefined if the former is >= the latter. + */ + PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD } PP_URLRequestProperty; PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_URLRequestProperty, 4); /** diff --git a/ppapi/cpp/url_request_info.h b/ppapi/cpp/url_request_info.h index cce4e91..f0922a5 100644 --- a/ppapi/cpp/url_request_info.h +++ b/ppapi/cpp/url_request_info.h @@ -70,6 +70,14 @@ class URLRequestInfo : public Resource { return SetProperty(PP_URLREQUESTPROPERTY_CUSTOMCONTENTTRANSFERENCODING, content_transfer_encoding); } + bool SetPrefetchBufferUpperThreshold(int32_t size) { + return SetProperty(PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD, + size); + } + bool SetPrefetchBufferLowerThreshold(int32_t size) { + return SetProperty(PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD, + size); + } }; } // namespace pp diff --git a/webkit/plugins/ppapi/ppb_url_loader_impl.cc b/webkit/plugins/ppapi/ppb_url_loader_impl.cc index 27ec617..5684d40 100644 --- a/webkit/plugins/ppapi/ppb_url_loader_impl.cc +++ b/webkit/plugins/ppapi/ppb_url_loader_impl.cc @@ -208,6 +208,8 @@ PPB_URLLoader_Impl::PPB_URLLoader_Impl(PluginInstance* instance, user_buffer_(NULL), user_buffer_size_(0), done_status_(PP_OK_COMPLETIONPENDING), + is_streaming_to_file_(false), + is_asynchronous_load_suspended_(false), has_universal_access_(false), status_callback_(NULL) { } @@ -268,6 +270,7 @@ int32_t PPB_URLLoader_Impl::Open(PPB_URLRequestInfo_Impl* request, options.allowCredentials = request->allow_credentials(); } + is_asynchronous_load_suspended_ = false; loader_.reset(frame->createAssociatedURLLoader(options)); if (!loader_.get()) return PP_ERROR_FAILED; @@ -365,6 +368,12 @@ int32_t PPB_URLLoader_Impl::FinishStreamingToFile( if (done_status_ != PP_OK_COMPLETIONPENDING) return done_status_; + is_streaming_to_file_ = true; + if (is_asynchronous_load_suspended_) { + loader_->setDefersLoading(false); + is_asynchronous_load_suspended_ = false; + } + // Wait for didFinishLoading / didFail. RegisterCallback(callback); return PP_OK_COMPLETIONPENDING; @@ -440,6 +449,20 @@ void PPB_URLLoader_Impl::didReceiveData(WebURLLoader* loader, } else { DCHECK(!pending_callback_.get() || pending_callback_->completed()); } + + // To avoid letting the network stack download an entire stream all at once, + // defer loading when we have enough buffer. + // Check the buffer size after potentially moving some to the user buffer. + DCHECK(request_info_->prefetch_buffer_lower_threshold() < + request_info_->prefetch_buffer_upper_threshold()); + if (!is_streaming_to_file_ && + !is_asynchronous_load_suspended_ && + buffer_.size() >= static_cast<size_t>( + request_info_->prefetch_buffer_upper_threshold())) { + DVLOG(1) << "Suspending async load - buffer size: " << buffer_.size(); + loader->setDefersLoading(true); + is_asynchronous_load_suspended_ = true; + } } void PPB_URLLoader_Impl::didFinishLoading(WebURLLoader* loader, @@ -498,6 +521,15 @@ size_t PPB_URLLoader_Impl::FillUserBuffer() { std::copy(buffer_.begin(), buffer_.begin() + bytes_to_copy, user_buffer_); buffer_.erase(buffer_.begin(), buffer_.begin() + bytes_to_copy); + // If the buffer is getting too empty, resume asynchronous loading. + if (is_asynchronous_load_suspended_ && + buffer_.size() <= static_cast<size_t>( + request_info_->prefetch_buffer_lower_threshold())) { + DVLOG(1) << "Resuming async load - buffer size: " << buffer_.size(); + loader_->setDefersLoading(false); + is_asynchronous_load_suspended_ = false; + } + // Reset for next time. user_buffer_ = NULL; user_buffer_size_ = 0; diff --git a/webkit/plugins/ppapi/ppb_url_loader_impl.h b/webkit/plugins/ppapi/ppb_url_loader_impl.h index fae3628..878ce65 100644 --- a/webkit/plugins/ppapi/ppb_url_loader_impl.h +++ b/webkit/plugins/ppapi/ppb_url_loader_impl.h @@ -137,6 +137,8 @@ class PPB_URLLoader_Impl : public Resource, public WebKit::WebURLLoaderClient { char* user_buffer_; size_t user_buffer_size_; int32_t done_status_; + bool is_streaming_to_file_; + bool is_asynchronous_load_suspended_; bool has_universal_access_; diff --git a/webkit/plugins/ppapi/ppb_url_request_info_impl.cc b/webkit/plugins/ppapi/ppb_url_request_info_impl.cc index 7bae8ba..90a0ec6 100644 --- a/webkit/plugins/ppapi/ppb_url_request_info_impl.cc +++ b/webkit/plugins/ppapi/ppb_url_request_info_impl.cc @@ -34,6 +34,9 @@ namespace ppapi { namespace { +const int32_t kDefaultPrefetchBufferUpperThreshold = 100 * 1000 * 1000; +const int32_t kDefaultPrefetchBufferLowerThreshold = 50 * 1000 * 1000; + // A header string containing any of the following fields will cause // an error. The list comes from the XMLHttpRequest standard. // http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader-method @@ -113,6 +116,10 @@ PP_Bool SetProperty(PP_Resource request_id, request->SetBooleanProperty(property, PPBoolToBool(var.value.as_bool))); break; + case PP_VARTYPE_INT32: + result = BoolToPPBool( + request->SetIntegerProperty(property, var.value.as_int)); + break; case PP_VARTYPE_STRING: { scoped_refptr<StringVar> string(StringVar::FromPPVar(var)); if (string) @@ -203,7 +210,9 @@ PPB_URLRequestInfo_Impl::PPB_URLRequestInfo_Impl(PluginInstance* instance) has_custom_referrer_url_(false), allow_cross_origin_requests_(false), allow_credentials_(false), - has_custom_content_transfer_encoding_(false) { + has_custom_content_transfer_encoding_(false), + prefetch_buffer_upper_threshold_(kDefaultPrefetchBufferUpperThreshold), + prefetch_buffer_lower_threshold_(kDefaultPrefetchBufferLowerThreshold) { } PPB_URLRequestInfo_Impl::~PPB_URLRequestInfo_Impl() { @@ -260,6 +269,20 @@ bool PPB_URLRequestInfo_Impl::SetBooleanProperty(PP_URLRequestProperty property, } } +bool PPB_URLRequestInfo_Impl::SetIntegerProperty(PP_URLRequestProperty property, + int32_t value) { + switch (property) { + case PP_URLREQUESTPROPERTY_PREFETCHBUFFERUPPERTHRESHOLD: + prefetch_buffer_upper_threshold_ = value; + return true; + case PP_URLREQUESTPROPERTY_PREFETCHBUFFERLOWERTHRESHOLD: + prefetch_buffer_lower_threshold_ = value; + return true; + default: + return false; + } +} + bool PPB_URLRequestInfo_Impl::SetStringProperty(PP_URLRequestProperty property, const std::string& value) { // TODO(darin): Validate input. Perhaps at a different layer? diff --git a/webkit/plugins/ppapi/ppb_url_request_info_impl.h b/webkit/plugins/ppapi/ppb_url_request_info_impl.h index 9d6c766..2cdf3e4 100644 --- a/webkit/plugins/ppapi/ppb_url_request_info_impl.h +++ b/webkit/plugins/ppapi/ppb_url_request_info_impl.h @@ -37,6 +37,7 @@ class PPB_URLRequestInfo_Impl : public Resource { // PPB_URLRequestInfo implementation. bool SetUndefinedProperty(PP_URLRequestProperty property); bool SetBooleanProperty(PP_URLRequestProperty property, bool value); + bool SetIntegerProperty(PP_URLRequestProperty property, int32_t value); bool SetStringProperty(PP_URLRequestProperty property, const std::string& value); bool AppendDataToBody(const std::string& data); @@ -60,6 +61,13 @@ class PPB_URLRequestInfo_Impl : public Resource { } bool allow_credentials() const { return allow_credentials_; } + int32_t prefetch_buffer_upper_threshold() const { + return prefetch_buffer_upper_threshold_; + } + int32_t prefetch_buffer_lower_threshold() const { + return prefetch_buffer_lower_threshold_; + } + private: struct BodyItem; typedef std::vector<BodyItem> Body; @@ -89,6 +97,10 @@ class PPB_URLRequestInfo_Impl : public Resource { bool has_custom_content_transfer_encoding_; std::string custom_content_transfer_encoding_; + // Specify permitted range for the size of the buffer unconsumed by plugin. + int32_t prefetch_buffer_upper_threshold_; + int32_t prefetch_buffer_lower_threshold_; + DISALLOW_COPY_AND_ASSIGN(PPB_URLRequestInfo_Impl); }; |