summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-04 16:19:14 +0000
committerddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-04 16:19:14 +0000
commit80c71de2dbd4ee5fd78a598b06daffacf3a35a7f (patch)
tree1eecec7747a9179a56b072365fac697214e699ef
parent8f7320ed810cf0409aadae175d42463fdaebe1ab (diff)
downloadchromium_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.h29
-rw-r--r--ppapi/cpp/url_request_info.h8
-rw-r--r--webkit/plugins/ppapi/ppb_url_loader_impl.cc32
-rw-r--r--webkit/plugins/ppapi/ppb_url_loader_impl.h2
-rw-r--r--webkit/plugins/ppapi/ppb_url_request_info_impl.cc25
-rw-r--r--webkit/plugins/ppapi/ppb_url_request_info_impl.h12
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);
};