diff options
author | dschuff@chromium.org <dschuff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-10 21:08:21 +0000 |
---|---|---|
committer | dschuff@chromium.org <dschuff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-10 21:08:21 +0000 |
commit | 3e74ca463ead93ccd33c843382dcf4e083d7432b (patch) | |
tree | 87fe21946a23232fa53c2bdaa7bec5b5a8d4f73d /ppapi | |
parent | bd9b7b95187249f588acc4f5a61cf37c5b686817 (diff) | |
download | chromium_src-3e74ca463ead93ccd33c843382dcf4e083d7432b.zip chromium_src-3e74ca463ead93ccd33c843382dcf4e083d7432b.tar.gz chromium_src-3e74ca463ead93ccd33c843382dcf4e083d7432b.tar.bz2 |
Renderer and IPC implementation for new PNaCl translation cache
Creates new IPCs which the renderer/plugin will use to request a temp file descriptor for the translated nexe. In the future the browser will check the cache and may return the cached translation. In this CL, the browser simply creates a new temp file via the existing mechanism and sends it back with an indication that the cache missed. Also creates another IPC to notify the browser that the translation has finished. In a future CL it will cause the browser to try to cache the translation. Details on the design can be found in http://goo.gl/8mgYS
In addition to the IPCs, this CL creates PnaclTranslationResourceHost in the renderer to track the outstanding translation cache requests and fills out the implementation of the NaCl private pepper interfaces which correspond to the IPCs. It also refactors nacl_file_host::CreateTemporaryFile so that it can more easily be used to implement both the existing CreateTemporaryFile IPC (which is still used for the object file) and the new NexeTempFileRequest IPC (which is used for the final linked nexe).
BUG= https://code.google.com/p/nativeclient/issues/detail?id=3372
TEST= browser_tests --gtest_filter=NaClBrowserTestPnaclWithNewCache.*:NaClBrowserTestPnacl.*
R=binji@chromium.org, dmichael@chromium.org, jschuh@chromium.org, jvoung@chromium.org, thakis@chromium.org, yzshen@chromium.org
Review URL: https://codereview.chromium.org/17839005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@210927 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
7 files changed, 62 insertions, 27 deletions
diff --git a/ppapi/api/private/ppb_nacl_private.idl b/ppapi/api/private/ppb_nacl_private.idl index a687bc2..e8d3276 100644 --- a/ppapi/api/private/ppb_nacl_private.idl +++ b/ppapi/api/private/ppb_nacl_private.idl @@ -110,7 +110,8 @@ interface PPB_NaCl_Private { /* Create a temporary file, which will be deleted by the time the last * handle is closed (or earlier on POSIX systems), to use for the nexe - * with the cache key given by |cache_key|. If the nexe is already present + * with the cache information given by |pexe_url|, |abi_version|, |opt_level|, + * |last_modified|, and |etag|. If the nexe is already present * in the cache, |is_hit| is set to PP_TRUE and the contents of the nexe * will be copied into the temporary file. Otherwise |is_hit| is set to * PP_FALSE and the temporary file will be writeable. @@ -121,7 +122,11 @@ interface PPB_NaCl_Private { * translation finishes. */ int32_t GetNexeFd([in] PP_Instance instance, - [in] str_t cache_key, + [in] str_t pexe_url, + [in] uint32_t abi_version, + [in] uint32_t opt_level, + [in] str_t last_modified, + [in] str_t etag, [out] PP_Bool is_hit, [out] PP_FileHandle nexe_handle, [in] PP_CompletionCallback callback); diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h index 2b6c215..5ebfa7c 100644 --- a/ppapi/c/private/ppb_nacl_private.h +++ b/ppapi/c/private/ppb_nacl_private.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From private/ppb_nacl_private.idl modified Tue Jun 25 15:57:09 2013. */ +/* From private/ppb_nacl_private.idl modified Wed Jul 3 17:49:33 2013. */ #ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ #define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_ @@ -128,7 +128,8 @@ struct PPB_NaCl_Private_1_0 { PP_FileHandle (*CreateTemporaryFile)(PP_Instance instance); /* Create a temporary file, which will be deleted by the time the last * handle is closed (or earlier on POSIX systems), to use for the nexe - * with the cache key given by |cache_key|. If the nexe is already present + * with the cache information given by |pexe_url|, |abi_version|, |opt_level|, + * |last_modified|, and |etag|. If the nexe is already present * in the cache, |is_hit| is set to PP_TRUE and the contents of the nexe * will be copied into the temporary file. Otherwise |is_hit| is set to * PP_FALSE and the temporary file will be writeable. @@ -139,7 +140,11 @@ struct PPB_NaCl_Private_1_0 { * translation finishes. */ int32_t (*GetNexeFd)(PP_Instance instance, - const char* cache_key, + const char* pexe_url, + uint32_t abi_version, + uint32_t opt_level, + const char* last_modified, + const char* etag, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback callback); diff --git a/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers.cc b/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers.cc index 12fc1a3..bad629a 100644 --- a/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers.cc +++ b/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers.cc @@ -71,19 +71,27 @@ void NaClHttpResponseHeaders::Parse(const std::string& headers_str) { } } -std::string NaClHttpResponseHeaders::GetCacheValidators() { - std::string result; +std::string NaClHttpResponseHeaders::GetHeader(const std::string& name) { for (size_t i = 0; i < header_entries_.size(); ++i) { const Entry& entry = header_entries_[i]; std::string key = entry.first; // TODO(jvoung): replace with LowerCaseEqualsASCII later. std::transform(key.begin(), key.end(), key.begin(), ::tolower); - if (key.compare("etag") == 0 || key.compare("last-modified") == 0) { - if (!result.empty()) - result += "&"; - // Return the original headers, not the tolower ones. - result += entry.first + ":" + entry.second; - } + if (key.compare(name) == 0) + return entry.second; + } + return std::string(); +} + +std::string NaClHttpResponseHeaders::GetCacheValidators() { + std::string result = GetHeader("etag"); + if (!result.empty()) + result = "etag:" + result; + std::string lm = GetHeader("last-modified"); + if (!lm.empty()) { + if (!result.empty()) + result += "&"; + result += "last-modified:" + lm; } return result; } diff --git a/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers.h b/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers.h index 181a381..60ab2c5 100644 --- a/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers.h +++ b/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers.h @@ -40,6 +40,9 @@ class NaClHttpResponseHeaders { // Invalid header lines are skipped. void Parse(const std::string& headers_str); + // Get the value of the header named |name| + std::string GetHeader(const std::string& name); + // Return a concatenated string of HTTP caching validators. // E.g., Last-Modified time and ETags. std::string GetCacheValidators(); diff --git a/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers_unittest.cc b/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers_unittest.cc index 80582b9..12d1f12 100644 --- a/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers_unittest.cc +++ b/ppapi/native_client/src/trusted/plugin/nacl_http_response_headers_unittest.cc @@ -18,10 +18,12 @@ TEST(NaClHttpResponseHeadersTest, TestGetValidators) { "Accept-Ranges: bytes\n" "ETag: w\"abcdefg\"\n" "Content-Length: 2912652\n"); - std::string one_val_expected("ETag:w\"abcdefg\""); + std::string one_val_expected("etag:w\"abcdefg\""); plugin::NaClHttpResponseHeaders parser_1; parser_1.Parse(one_val_headers); - EXPECT_EQ(parser_1.GetCacheValidators(), one_val_expected); + EXPECT_EQ(one_val_expected, parser_1.GetCacheValidators()); + EXPECT_EQ(std::string("w\"abcdefg\""), parser_1.GetHeader("etag")); + EXPECT_EQ(std::string(), parser_1.GetHeader("last-modified")); // Test a Last-Modified Header. std::string mod_val_headers("Date: Wed, 15 Nov 1995 06:25:24 GMT\n" @@ -31,10 +33,12 @@ TEST(NaClHttpResponseHeadersTest, TestGetValidators) { "Accept-Ranges: bytes\n" "Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT\n" "Content-Length: 2912652\n"); - std::string mod_val_expected("Last-Modified:Wed, 15 Nov 1995 04:58:08 GMT"); + std::string mod_val_expected("last-modified:Wed, 15 Nov 1995 04:58:08 GMT"); plugin::NaClHttpResponseHeaders parser_1b; parser_1b.Parse(mod_val_headers); - EXPECT_EQ(parser_1b.GetCacheValidators(), mod_val_expected); + EXPECT_EQ(mod_val_expected, parser_1b.GetCacheValidators()); + EXPECT_EQ(std::string("Wed, 15 Nov 1995 04:58:08 GMT"), + parser_1b.GetHeader("last-modified")); // Test both (strong) ETag and Last-Modified, with some whitespace. std::string two_val_headers("Date: Wed, 15 Nov 1995 06:25:24 GMT\n" @@ -47,20 +51,24 @@ TEST(NaClHttpResponseHeadersTest, TestGetValidators) { "Accept-Ranges: bytes\n" "Content-Length: 2912652\n"); // Note that the value can still have white-space. - std::string two_val_expected("Last-modified:Wed, 15 Nov 1995 04:58:08 GMT&" - "etag:\"/abcdefg:A-Z0-9+/==\""); + std::string two_val_expected("etag:\"/abcdefg:A-Z0-9+/==\"&" + "last-modified:Wed, 15 Nov 1995 04:58:08 GMT"); plugin::NaClHttpResponseHeaders parser_2; parser_2.Parse(two_val_headers); - EXPECT_EQ(parser_2.GetCacheValidators(), two_val_expected); + EXPECT_EQ(two_val_expected, parser_2.GetCacheValidators()); + EXPECT_EQ(std::string("\"/abcdefg:A-Z0-9+/==\""), + parser_2.GetHeader("etag")); // Some etag generators like python HTTP server use ' instead of " std::string single_q_headers("Date: Wed, 15 Nov 1995 06:25:24 GMT\n" "Server: BaseHTTP/0.3 Python/2.7.3\n" "ETag: '/usr/local/some_file.nmf'\n"); - std::string single_q_expected("ETag:'/usr/local/some_file.nmf'"); + std::string single_q_expected("etag:'/usr/local/some_file.nmf'"); plugin::NaClHttpResponseHeaders parser_3; parser_3.Parse(single_q_headers); - EXPECT_EQ(parser_3.GetCacheValidators(), single_q_expected); + EXPECT_EQ(single_q_expected, parser_3.GetCacheValidators()); + EXPECT_EQ(std::string("'/usr/local/some_file.nmf'"), + parser_3.GetHeader("etag")); // Keys w/ leading whitespace are invalid. // See: HttpResponseHeadersTest.NormalizeHeadersLeadingWhitespace. @@ -70,7 +78,8 @@ TEST(NaClHttpResponseHeadersTest, TestGetValidators) { std::string bad_expected(""); plugin::NaClHttpResponseHeaders parser_4; parser_4.Parse(bad_headers); - EXPECT_EQ(parser_4.GetCacheValidators(), bad_expected); + EXPECT_EQ(bad_expected, parser_4.GetCacheValidators()); + EXPECT_EQ(bad_expected, parser_4.GetHeader("etag")); } // Test that we are able to determine when there is a no-store diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index b042f0e..3f4cfab 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -846,7 +846,12 @@ void PnaclCoordinator::BitcodeStreamDidOpen(int32_t pp_error) { int32_t nexe_fd_err = plugin_->nacl_interface()->GetNexeFd( plugin_->pp_instance(), - pnacl_options_.GetCacheKey().c_str(), + streaming_downloader_->url().c_str(), + // TODO(dschuff): use the right abi version here. + 0, + pnacl_options_.opt_level(), + parser.GetHeader("last-modified").c_str(), + parser.GetHeader("etag").c_str(), &is_cache_hit_, &nexe_handle_, cb.pp_completion_callback()); diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index d85099d..2ce717c 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -2783,9 +2783,9 @@ static PP_FileHandle Pnacl_M13_PPB_NaCl_Private_CreateTemporaryFile(PP_Instance return iface->CreateTemporaryFile(instance); } -static int32_t Pnacl_M13_PPB_NaCl_Private_GetNexeFd(PP_Instance instance, const char* cache_key, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback* callback) { +static int32_t Pnacl_M13_PPB_NaCl_Private_GetNexeFd(PP_Instance instance, const char* pexe_url, uint32_t abi_version, uint32_t opt_level, const char* last_modified, const char* etag, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback* callback) { const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; - return iface->GetNexeFd(instance, cache_key, is_hit, nexe_handle, *callback); + return iface->GetNexeFd(instance, pexe_url, abi_version, opt_level, last_modified, etag, is_hit, nexe_handle, *callback); } static void Pnacl_M13_PPB_NaCl_Private_ReportTranslationFinished(PP_Instance instance) { @@ -4580,7 +4580,7 @@ struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = { .BrokerDuplicateHandle = (int32_t (*)(PP_FileHandle source_handle, uint32_t process_id, PP_FileHandle* target_handle, uint32_t desired_access, uint32_t options))&Pnacl_M13_PPB_NaCl_Private_BrokerDuplicateHandle, .GetReadonlyPnaclFd = (PP_FileHandle (*)(const char* filename))&Pnacl_M13_PPB_NaCl_Private_GetReadonlyPnaclFd, .CreateTemporaryFile = (PP_FileHandle (*)(PP_Instance instance))&Pnacl_M13_PPB_NaCl_Private_CreateTemporaryFile, - .GetNexeFd = (int32_t (*)(PP_Instance instance, const char* cache_key, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback callback))&Pnacl_M13_PPB_NaCl_Private_GetNexeFd, + .GetNexeFd = (int32_t (*)(PP_Instance instance, const char* pexe_url, uint32_t abi_version, uint32_t opt_level, const char* last_modified, const char* etag, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback callback))&Pnacl_M13_PPB_NaCl_Private_GetNexeFd, .ReportTranslationFinished = (void (*)(PP_Instance instance))&Pnacl_M13_PPB_NaCl_Private_ReportTranslationFinished, .IsOffTheRecord = (PP_Bool (*)(void))&Pnacl_M13_PPB_NaCl_Private_IsOffTheRecord, .IsPnaclEnabled = (PP_Bool (*)(void))&Pnacl_M13_PPB_NaCl_Private_IsPnaclEnabled, |