summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extension_protocols.cc
diff options
context:
space:
mode:
authorpaivanof@gmail.com <paivanof@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-23 17:15:10 +0000
committerpaivanof@gmail.com <paivanof@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-23 17:15:10 +0000
commit36ffc73476203ce0ab507e79e481702e317a6922 (patch)
tree8dde21160cfeb6e5ae42643470226f19bd2e6b2d /chrome/browser/extensions/extension_protocols.cc
parent9b000129350fe5a26574a013c44915b23acf2918 (diff)
downloadchromium_src-36ffc73476203ce0ab507e79e481702e317a6922.zip
chromium_src-36ffc73476203ce0ab507e79e481702e317a6922.tar.gz
chromium_src-36ffc73476203ce0ab507e79e481702e317a6922.tar.bz2
Offload disk accesses to WorkerPool in ExtensionProtocolHandler
and URLRequestResourceBundleJob. To achieve that URLRequestSimpleJob::GetData() signature changed to allow async operation finishing. All places implementing GetData() are updated. Patch from Pavel Ivanov <paivanof@gmail.com> BUG=59849,90207 Review URL: https://chromiumcodereview.appspot.com/10696135 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147869 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/extension_protocols.cc')
-rw-r--r--chrome/browser/extensions/extension_protocols.cc129
1 files changed, 90 insertions, 39 deletions
diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc
index 59e12d9..ceada7e 100644
--- a/chrome/browser/extensions/extension_protocols.cc
+++ b/chrome/browser/extensions/extension_protocols.cc
@@ -9,11 +9,13 @@
#include "base/compiler_specific.h"
#include "base/file_path.h"
#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/threading/thread_restrictions.h"
+#include "base/threading/worker_pool.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_info_map.h"
#include "chrome/browser/net/chrome_url_request_context.h"
@@ -58,6 +60,12 @@ net::HttpResponseHeaders* BuildHttpHeaders(
return new net::HttpResponseHeaders(raw_headers);
}
+void ReadMimeTypeFromFile(const FilePath& filename,
+ std::string* mime_type,
+ bool* result) {
+ *result = net::GetMimeTypeFromFile(filename, mime_type);
+}
+
class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
public:
URLRequestResourceBundleJob(
@@ -65,35 +73,38 @@ class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
const std::string& content_security_policy, bool send_cors_header)
: net::URLRequestSimpleJob(request),
filename_(filename),
- resource_id_(resource_id) {
+ resource_id_(resource_id),
+ weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
response_info_.headers = BuildHttpHeaders(content_security_policy,
send_cors_header);
}
// Overridden from URLRequestSimpleJob:
- virtual bool GetData(std::string* mime_type,
- std::string* charset,
- std::string* data) const OVERRIDE {
+ virtual int GetData(std::string* mime_type,
+ std::string* charset,
+ std::string* data,
+ const net::CompletionCallback& callback) const OVERRIDE {
const ResourceBundle& rb = ResourceBundle::GetSharedInstance();
*data = rb.GetRawDataResource(
resource_id_, ui::SCALE_FACTOR_NONE).as_string();
- // Requests should not block on the disk! On Windows this goes to the
- // registry.
- // http://code.google.com/p/chromium/issues/detail?id=59849
- bool result;
- {
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- result = net::GetMimeTypeFromFile(filename_, mime_type);
- }
-
- if (StartsWithASCII(*mime_type, "text/", false)) {
- // All of our HTML files should be UTF-8 and for other resource types
- // (like images), charset doesn't matter.
- DCHECK(IsStringUTF8(*data));
- *charset = "utf-8";
- }
- return result;
+ std::string* read_mime_type = new std::string;
+ bool* read_result = new bool;
+ bool posted = base::WorkerPool::PostTaskAndReply(
+ FROM_HERE,
+ base::Bind(&ReadMimeTypeFromFile, filename_,
+ base::Unretained(read_mime_type),
+ base::Unretained(read_result)),
+ base::Bind(&URLRequestResourceBundleJob::OnMimeTypeRead,
+ weak_factory_.GetWeakPtr(),
+ mime_type, charset, data,
+ base::Owned(read_mime_type),
+ base::Owned(read_result),
+ callback),
+ true /* task is slow */);
+ DCHECK(posted);
+
+ return net::ERR_IO_PENDING;
}
virtual void GetResponseInfo(net::HttpResponseInfo* info) {
@@ -103,6 +114,23 @@ class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
private:
virtual ~URLRequestResourceBundleJob() { }
+ void OnMimeTypeRead(std::string* out_mime_type,
+ std::string* charset,
+ std::string* data,
+ std::string* read_mime_type,
+ bool* read_result,
+ const net::CompletionCallback& callback) {
+ *out_mime_type = *read_mime_type;
+ if (StartsWithASCII(*read_mime_type, "text/", false)) {
+ // All of our HTML files should be UTF-8 and for other resource types
+ // (like images), charset doesn't matter.
+ DCHECK(IsStringUTF8(*data));
+ *charset = "utf-8";
+ }
+ int result = *read_result? net::OK: net::ERR_INVALID_URL;
+ callback.Run(result);
+ }
+
// We need the filename of the resource to determine the mime type.
FilePath filename_;
@@ -110,6 +138,8 @@ class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
int resource_id_;
net::HttpResponseInfo response_info_;
+
+ mutable base::WeakPtrFactory<URLRequestResourceBundleJob> weak_factory_;
};
class GeneratedBackgroundPageJob : public net::URLRequestSimpleJob {
@@ -125,9 +155,10 @@ class GeneratedBackgroundPageJob : public net::URLRequestSimpleJob {
}
// Overridden from URLRequestSimpleJob:
- virtual bool GetData(std::string* mime_type,
- std::string* charset,
- std::string* data) const OVERRIDE {
+ virtual int GetData(std::string* mime_type,
+ std::string* charset,
+ std::string* data,
+ const net::CompletionCallback& callback) const OVERRIDE {
*mime_type = "text/html";
*charset = "utf-8";
@@ -138,7 +169,7 @@ class GeneratedBackgroundPageJob : public net::URLRequestSimpleJob {
*data += "\"></script>\n";
}
- return true;
+ return net::OK;
}
virtual void GetResponseInfo(net::HttpResponseInfo* info) {
@@ -152,13 +183,25 @@ class GeneratedBackgroundPageJob : public net::URLRequestSimpleJob {
net::HttpResponseInfo response_info_;
};
+void ReadResourceFilePath(const ExtensionResource& resource,
+ FilePath* file_path) {
+ *file_path = resource.GetFilePath();
+}
+
class URLRequestExtensionJob : public net::URLRequestFileJob {
public:
URLRequestExtensionJob(net::URLRequest* request,
- const FilePath& filename,
+ const std::string& extension_id,
+ const FilePath& directory_path,
const std::string& content_security_policy,
bool send_cors_header)
- : net::URLRequestFileJob(request, filename) {
+ : net::URLRequestFileJob(request, FilePath()),
+ // TODO(tc): Move all of these files into resources.pak so we don't break
+ // when updating on Linux.
+ resource_(extension_id, directory_path,
+ extension_file_util::ExtensionURLToRelativeFilePath(
+ request->url())),
+ weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
response_info_.headers = BuildHttpHeaders(content_security_policy,
send_cors_header);
}
@@ -167,10 +210,30 @@ class URLRequestExtensionJob : public net::URLRequestFileJob {
*info = response_info_;
}
+ virtual void Start() OVERRIDE {
+ FilePath* read_file_path = new FilePath;
+ bool posted = base::WorkerPool::PostTaskAndReply(
+ FROM_HERE,
+ base::Bind(&ReadResourceFilePath, resource_,
+ base::Unretained(read_file_path)),
+ base::Bind(&URLRequestExtensionJob::OnFilePathRead,
+ weak_factory_.GetWeakPtr(),
+ base::Owned(read_file_path)),
+ true /* task is slow */);
+ DCHECK(posted);
+ }
+
private:
virtual ~URLRequestExtensionJob() {}
+ void OnFilePathRead(FilePath* read_file_path) {
+ file_path_ = *read_file_path;
+ URLRequestFileJob::Start();
+ }
+
net::HttpResponseInfo response_info_;
+ ExtensionResource resource_;
+ base::WeakPtrFactory<URLRequestExtensionJob> weak_factory_;
};
bool ExtensionCanLoadInIncognito(const ResourceRequestInfo* info,
@@ -322,20 +385,8 @@ ExtensionProtocolHandler::MaybeCreateJob(net::URLRequest* request) const {
}
}
}
- // TODO(tc): Move all of these files into resources.pak so we don't break
- // when updating on Linux.
- ExtensionResource resource(extension_id, directory_path,
- extension_file_util::ExtensionURLToRelativeFilePath(request->url()));
-
- FilePath resource_file_path;
- {
- // Getting the file path will touch the file system. Fixing
- // crbug.com/59849 would also fix this. Suppress the error for now.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- resource_file_path = resource.GetFilePath();
- }
- return new URLRequestExtensionJob(request, resource_file_path,
+ return new URLRequestExtensionJob(request, extension_id, directory_path,
content_security_policy, send_cors_header);
}