diff options
author | jvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-23 02:25:12 +0000 |
---|---|---|
committer | jvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-23 02:25:12 +0000 |
commit | 84ed8ce8e9a43e56a5d3219acc77020e9462c3d7 (patch) | |
tree | 4870a03efdab43575e88da4a08a483e1ddcc5cbf /ppapi/native_client/src | |
parent | aa09ea70f13030b9e0bfc837a0f0364167c29302 (diff) | |
download | chromium_src-84ed8ce8e9a43e56a5d3219acc77020e9462c3d7.zip chromium_src-84ed8ce8e9a43e56a5d3219acc77020e9462c3d7.tar.gz chromium_src-84ed8ce8e9a43e56a5d3219acc77020e9462c3d7.tar.bz2 |
Plumb through cache_identity from manifest for first sketch of pnacl cache. Probe cache for lookups.
BUG= http://code.google.com/p/nativeclient/issues/detail?id=1714
TEST= run_pnacl_example_browser_test
Review URL: https://chromiumcodereview.appspot.com/9355051
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123178 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/native_client/src')
8 files changed, 179 insertions, 75 deletions
diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.cc b/ppapi/native_client/src/trusted/plugin/json_manifest.cc index af38a2f..81d956d 100644 --- a/ppapi/native_client/src/trusted/plugin/json_manifest.cc +++ b/ppapi/native_client/src/trusted/plugin/json_manifest.cc @@ -39,13 +39,21 @@ const char* const kPortableKey = "portable"; const char* const kPnaclTranslateKey = "pnacl-translate"; const char* const kUrlKey = "url"; +// Cache support keys +const char* const kCacheIdentityKey = "sha256"; + // Sample manifest file: // { // "program": { // "x86-32": {"url": "myprogram_x86-32.nexe"}, // "x86-64": {"url": "myprogram_x86-64.nexe"}, // "arm": {"url": "myprogram_arm.nexe"}, -// "portable": {"pnacl-translate": {"url": "myprogram.pexe"} } +// "portable": { +// "pnacl-translate": { +// "url": "myprogram.pexe", +// "sha256": "..." +// } +// } // }, // "interpreter": { // "x86-32": {"url": "interpreter_x86-32.nexe"}, @@ -136,14 +144,18 @@ bool IsValidUrlSpec(const Json::Value& url_spec, const nacl::string& container_key, const nacl::string& parent_key, nacl::string* error_string) { - static const char* kManifestUrlSpecProperties[] = { + static const char* kManifestUrlSpecRequired[] = { kUrlKey }; + static const char* kManifestUrlSpecPlusOptional[] = { + kUrlKey, + kCacheIdentityKey + }; if (!IsValidDictionary(url_spec, container_key, parent_key, - kManifestUrlSpecProperties, - NACL_ARRAY_SIZE(kManifestUrlSpecProperties), - kManifestUrlSpecProperties, - NACL_ARRAY_SIZE(kManifestUrlSpecProperties), + kManifestUrlSpecPlusOptional, + NACL_ARRAY_SIZE(kManifestUrlSpecPlusOptional), + kManifestUrlSpecRequired, + NACL_ARRAY_SIZE(kManifestUrlSpecRequired), error_string)) { return false; } @@ -246,19 +258,34 @@ bool IsValidISADictionary(const Json::Value& dictionary, return true; } +void GrabUrlAndCacheIdentity(const Json::Value& url_spec, + nacl::string* url, + nacl::string* cache_identity) { + *url = url_spec[kUrlKey].asString(); + if (url_spec.isMember(kCacheIdentityKey)) { + *cache_identity = url_spec[kCacheIdentityKey].asString(); + } +} + bool GetURLFromISADictionary(const Json::Value& dictionary, const nacl::string& parent_key, const nacl::string& sandbox_isa, bool prefer_portable, nacl::string* url, + nacl::string* cache_identity, nacl::string* error_string, bool* pnacl_translate) { - if (url == NULL || error_string == NULL || pnacl_translate == NULL) + if (url == NULL || cache_identity == NULL || + error_string == NULL || pnacl_translate == NULL) return false; if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa, error_string)) return false; + *url = ""; + *cache_identity = ""; + *pnacl_translate = false; + // The call to IsValidISADictionary() above guarantees that either // sandbox_isa or kPortableKey is present in the dictionary. bool has_portable = dictionary.isMember(kPortableKey); @@ -273,12 +300,13 @@ bool GetURLFromISADictionary(const Json::Value& dictionary, // Check if this requires a pnacl-translate, otherwise just grab the URL. // We may have pnacl-translate for isa-specific bitcode for CPU tuning. if (isa_spec.isMember(kPnaclTranslateKey)) { - *url = isa_spec[kPnaclTranslateKey][kUrlKey].asString(); + GrabUrlAndCacheIdentity(isa_spec[kPnaclTranslateKey], url, cache_identity); *pnacl_translate = true; } else { - *url = isa_spec[kUrlKey].asString(); + GrabUrlAndCacheIdentity(isa_spec, url, cache_identity); *pnacl_translate = false; } + return true; } @@ -288,11 +316,10 @@ bool GetKeyUrl(const Json::Value& dictionary, const Manifest* manifest, bool prefer_portable, nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) { CHECK(full_url != NULL && error_info != NULL); - *full_url = ""; - *pnacl_translate = false; if (!dictionary.isMember(key)) { error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, "file key not found in manifest"); @@ -302,7 +329,8 @@ bool GetKeyUrl(const Json::Value& dictionary, nacl::string error_string; nacl::string relative_url; if (!GetURLFromISADictionary(isa_dict, key, sandbox_isa, prefer_portable, - &relative_url, &error_string, pnacl_translate)) { + &relative_url, cache_identity, + &error_string, pnacl_translate)) { error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, key + nacl::string(" manifest resolution error: ") + error_string); @@ -437,9 +465,11 @@ bool JsonManifest::ResolveURL(const nacl::string& relative_url, } bool JsonManifest::GetProgramURL(nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) const { - if (full_url == NULL || error_info == NULL || pnacl_translate == NULL) + if (full_url == NULL || cache_identity == NULL || + error_info == NULL || pnacl_translate == NULL) return false; Json::Value program = dictionary_[kProgramKey]; @@ -452,6 +482,7 @@ bool JsonManifest::GetProgramURL(nacl::string* full_url, sandbox_isa_, prefer_portable_, &nexe_url, + cache_identity, &error_string, pnacl_translate)) { error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, @@ -479,19 +510,19 @@ bool JsonManifest::GetFileKeys(std::set<nacl::string>* keys) const { bool JsonManifest::ResolveKey(const nacl::string& key, nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) const { NaClLog(3, "JsonManifest::ResolveKey(%s)\n", key.c_str()); // key must be one of kProgramKey or kFileKey '/' file-section-key - if (full_url == NULL || error_info == NULL || pnacl_translate == NULL) + if (full_url == NULL || cache_identity == NULL || + error_info == NULL || pnacl_translate == NULL) return false; - *full_url = ""; - *pnacl_translate = false; if (key == kProgramKey) { return GetKeyUrl(dictionary_, key, sandbox_isa_, this, prefer_portable_, - full_url, error_info, pnacl_translate); + full_url, cache_identity, error_info, pnacl_translate); } nacl::string::const_iterator p = find(key.begin(), key.end(), '/'); if (p == key.end()) { @@ -526,7 +557,7 @@ bool JsonManifest::ResolveKey(const nacl::string& key, return false; } return GetKeyUrl(files, rest, sandbox_isa_, this, prefer_portable_, - full_url, error_info, pnacl_translate); + full_url, cache_identity, error_info, pnacl_translate); } } // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.h b/ppapi/native_client/src/trusted/plugin/json_manifest.h index fd01621..df04c88 100644 --- a/ppapi/native_client/src/trusted/plugin/json_manifest.h +++ b/ppapi/native_client/src/trusted/plugin/json_manifest.h @@ -47,6 +47,7 @@ class JsonManifest : public Manifest { // manifest file. Sets |pnacl_translate| to |true| if the program is // portable bitcode that must be translated. virtual bool GetProgramURL(nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) const; @@ -68,6 +69,7 @@ class JsonManifest : public Manifest { // If there was an error, details are reported via error_info. virtual bool ResolveKey(const nacl::string& key, nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) const; diff --git a/ppapi/native_client/src/trusted/plugin/manifest.h b/ppapi/native_client/src/trusted/plugin/manifest.h index 18aed65..bce0a19 100644 --- a/ppapi/native_client/src/trusted/plugin/manifest.h +++ b/ppapi/native_client/src/trusted/plugin/manifest.h @@ -41,6 +41,7 @@ class Manifest { // manifest file. Sets |pnacl_translate| to |true| if the program is // requires pnacl translation. virtual bool GetProgramURL(nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) const = 0; @@ -62,6 +63,7 @@ class Manifest { // If there was an error, details are reported via error_info. virtual bool ResolveKey(const nacl::string& key, nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) const = 0; diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc index c62c64a..0034f26 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.cc +++ b/ppapi/native_client/src/trusted/plugin/plugin.cc @@ -1471,6 +1471,7 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { HistogramSizeKB("NaCl.Perf.Size.Manifest", static_cast<int32_t>(manifest_json.length() / 1024)); nacl::string program_url; + nacl::string cache_identity; bool is_portable; ErrorInfo error_info; if (!SetManifestObject(manifest_json, &error_info)) { @@ -1478,7 +1479,8 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { return; } - if (SelectProgramURLFromManifest(&program_url, &error_info, &is_portable)) { + if (manifest_->GetProgramURL(&program_url, &cache_identity, + &error_info, &is_portable)) { set_nacl_ready_state(LOADING); // Inform JavaScript that we found a nexe URL to load. EnqueueProgressEvent(kProgressEventProgress); @@ -1489,6 +1491,7 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { pnacl_coordinator_.reset( PnaclCoordinator::BitcodeToNative(this, program_url, + cache_identity, translate_callback)); return; } else { @@ -1575,17 +1578,6 @@ bool Plugin::SetManifestObject(const nacl::string& manifest_json, return true; } -bool Plugin::SelectProgramURLFromManifest(nacl::string* result, - ErrorInfo* error_info, - bool* is_portable) { - const nacl::string sandbox_isa(GetSandboxISA()); - PLUGIN_PRINTF(("Plugin::SelectProgramURLFromManifest(): sandbox='%s'.\n", - sandbox_isa.c_str())); - if (result == NULL || error_info == NULL || manifest_ == NULL) - return false; - return manifest_->GetProgramURL(result, error_info, is_portable); -} - void Plugin::UrlDidOpenForStreamAsFile(int32_t pp_error, FileDownloader*& url_downloader, PP_CompletionCallback callback) { diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h index 3ddba50..2946181 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.h +++ b/ppapi/native_client/src/trusted/plugin/plugin.h @@ -400,16 +400,6 @@ class Plugin : public pp::InstancePrivate { bool SetManifestObject(const nacl::string& manifest_json, ErrorInfo* error_info); - // Determines the URL of the program module appropriate for the NaCl sandbox - // implemented by the installed sel_ldr. The URL is determined from the - // Manifest in |manifest_|. On success, |true| is returned and |result| is - // set to the URL to use for the program, and |is_portable| is set to - // |true| if the program is portable bitcode. - // On failure, |false| is returned. - bool SelectProgramURLFromManifest(nacl::string* result, - ErrorInfo* error_info, - bool* is_portable); - // Logs timing information to a UMA histogram, and also logs the same timing // information divided by the size of the nexe to another histogram. void HistogramStartupTimeSmall(const std::string& name, float dt); diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index cd0df60..e94de5f 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -74,15 +74,30 @@ const bool kWriteable = true; uint32_t LocalTempFile::next_identifier = 0; LocalTempFile::LocalTempFile(Plugin* plugin, + pp::FileSystem* file_system) + : plugin_(plugin), + file_system_(file_system) { + PLUGIN_PRINTF(("LocalTempFile::LocalTempFile (plugin=%p, " + "file_system=%p)\n", + static_cast<void*>(plugin), static_cast<void*>(file_system))); + Initialize(); +} + +LocalTempFile::LocalTempFile(Plugin* plugin, pp::FileSystem* file_system, - PnaclCoordinator* coordinator) + const nacl::string &filename) : plugin_(plugin), file_system_(file_system), - coordinator_(coordinator) { + filename_(nacl::string(kPnaclTempDir) + "/" + filename) { PLUGIN_PRINTF(("LocalTempFile::LocalTempFile (plugin=%p, " - "file_system=%p, coordinator=%p)\n", + "file_system=%p, filename=%s)\n", static_cast<void*>(plugin), static_cast<void*>(file_system), - static_cast<void*>(coordinator))); + filename.c_str())); + file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str())); + Initialize(); +} + +void LocalTempFile::Initialize() { callback_factory_.Initialize(this); rng_desc_ = (struct NaClDescRng *) malloc(sizeof *rng_desc_); CHECK(rng_desc_ != NULL); @@ -160,17 +175,21 @@ void LocalTempFile::WriteFileDidOpen(int32_t pp_error) { filename_ = ""; OpenWrite(done_callback_); } + // Run the client's completion callback. + pp::Core* core = pp::Module::Get()->core(); + if (pp_error != PP_OK) { + core->CallOnMainThread(0, done_callback_, pp_error); + return; + } // Remember the object temporary file descriptor. int32_t fd = GetFD(pp_error, *write_io_, kWriteable); if (fd < 0) { - coordinator_->ReportNonPpapiError("could not open write temp file."); + core->CallOnMainThread(0, done_callback_, pp_error); return; } // The descriptor for a writeable file needs to have quota management. write_wrapper_.reset( plugin_->wrapper_factory()->MakeFileDescQuota(fd, O_RDWR, identifier_)); - // Run the client's completion callback. - pp::Core* core = pp::Module::Get()->core(); core->CallOnMainThread(0, done_callback_, PP_OK); } @@ -187,15 +206,19 @@ void LocalTempFile::OpenRead(const pp::CompletionCallback& cb) { void LocalTempFile::ReadFileDidOpen(int32_t pp_error) { PLUGIN_PRINTF(("LocalTempFile::ReadFileDidOpen (pp_error=%" NACL_PRId32")\n", pp_error)); + // Run the client's completion callback. + pp::Core* core = pp::Module::Get()->core(); + if (pp_error != PP_OK) { + core->CallOnMainThread(0, done_callback_, pp_error); + return; + } // Remember the object temporary file descriptor. int32_t fd = GetFD(pp_error, *read_io_, kReadOnly); if (fd < 0) { - coordinator_->ReportNonPpapiError("could not open read temp file."); + core->CallOnMainThread(0, done_callback_, PP_ERROR_FAILED); return; } read_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); - // Run the client's completion callback. - pp::Core* core = pp::Module::Get()->core(); core->CallOnMainThread(0, done_callback_, PP_OK); } @@ -224,14 +247,21 @@ void LocalTempFile::Delete(const pp::CompletionCallback& cb) { void LocalTempFile::Rename(const nacl::string& new_name, const pp::CompletionCallback& cb) { - PLUGIN_PRINTF(("LocalTempFile::Rename\n")); // Rename the temporary file. - filename_ = new_name; - nacl::scoped_ptr<pp::FileRef> old_ref(file_ref_.release()); - file_ref_.reset(new pp::FileRef(*file_system_, new_name.c_str())); - old_ref->Rename(*file_ref_, cb); + filename_ = nacl::string(kPnaclTempDir) + "/" + new_name; + PLUGIN_PRINTF(("LocalTempFile::Rename to %s\n", filename_.c_str())); + // Remember the old ref until the rename is complete. + old_ref_.reset(file_ref_.release()); + file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str())); + old_ref_->Rename(*file_ref_, cb); +} + +void LocalTempFile::FinishRename() { + // Now we can release the old ref. + old_ref_.reset(NULL); } + ////////////////////////////////////////////////////////////////////// // Pnacl-specific manifest support. ////////////////////////////////////////////////////////////////////// @@ -243,10 +273,12 @@ class ExtensionManifest : public Manifest { virtual ~ExtensionManifest() { } virtual bool GetProgramURL(nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) const { // Does not contain program urls. UNREFERENCED_PARAMETER(full_url); + UNREFERENCED_PARAMETER(cache_identity); UNREFERENCED_PARAMETER(error_info); UNREFERENCED_PARAMETER(pnacl_translate); PLUGIN_PRINTF(("ExtensionManifest does not contain a program\n")); @@ -274,10 +306,13 @@ class ExtensionManifest : public Manifest { virtual bool ResolveKey(const nacl::string& key, nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) const { // All of the extension files are native (do not require pnacl translate). *pnacl_translate = false; + // Do not cache these entries. + *cache_identity = ""; // We can only resolve keys in the files/ namespace. const nacl::string kFilesPrefix = "files/"; size_t files_prefix_pos = key.find(kFilesPrefix); @@ -315,13 +350,15 @@ class PnaclLDManifest : public Manifest { virtual ~PnaclLDManifest() { } virtual bool GetProgramURL(nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) const { - if (nexe_manifest_->GetProgramURL(full_url, error_info, pnacl_translate)) { + if (nexe_manifest_->GetProgramURL(full_url, cache_identity, + error_info, pnacl_translate)) { return true; } - return extension_manifest_->GetProgramURL(full_url, error_info, - pnacl_translate); + return extension_manifest_->GetProgramURL(full_url, cache_identity, + error_info, pnacl_translate); } virtual bool ResolveURL(const nacl::string& relative_url, @@ -342,13 +379,14 @@ class PnaclLDManifest : public Manifest { virtual bool ResolveKey(const nacl::string& key, nacl::string* full_url, + nacl::string* cache_identity, ErrorInfo* error_info, bool* pnacl_translate) const { - if (nexe_manifest_->ResolveKey(key, full_url, + if (nexe_manifest_->ResolveKey(key, full_url, cache_identity, error_info, pnacl_translate)) { return true; } - return extension_manifest_->ResolveKey(key, full_url, + return extension_manifest_->ResolveKey(key, full_url, cache_identity, error_info, pnacl_translate); } @@ -365,11 +403,13 @@ class PnaclLDManifest : public Manifest { PnaclCoordinator* PnaclCoordinator::BitcodeToNative( Plugin* plugin, const nacl::string& pexe_url, + const nacl::string& cache_identity, const pp::CompletionCallback& translate_notify_callback) { PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", static_cast<void*>(plugin), pexe_url.c_str())); PnaclCoordinator* coordinator = - new PnaclCoordinator(plugin, pexe_url, translate_notify_callback); + new PnaclCoordinator(plugin, pexe_url, + cache_identity, translate_notify_callback); PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p)\n", reinterpret_cast<const void*>(coordinator->manifest_.get()))); // Load llc and ld. @@ -419,6 +459,7 @@ int32_t PnaclCoordinator::GetLoadedFileDesc(int32_t pp_error, PnaclCoordinator::PnaclCoordinator( Plugin* plugin, const nacl::string& pexe_url, + const nacl::string& cache_identity, const pp::CompletionCallback& translate_notify_callback) : plugin_(plugin), translate_notify_callback_(translate_notify_callback), @@ -426,6 +467,7 @@ PnaclCoordinator::PnaclCoordinator( file_system_(new pp::FileSystem(plugin, PP_FILESYSTEMTYPE_LOCALTEMPORARY)), manifest_(new ExtensionManifest(plugin->url_util())), pexe_url_(pexe_url), + cache_identity_(cache_identity), error_already_reported_(false) { PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", static_cast<void*>(this), static_cast<void*>(plugin))); @@ -530,21 +572,29 @@ void PnaclCoordinator::NexeFileWasClosed(int32_t pp_error) { ReportPpapiError(pp_error); return; } - // TODO(sehr): enable renaming once cache ids are available. // Rename the nexe file to the cache id. - // pp::CompletionCallback cb = - // callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); - // nexe_file_->Rename(new_name, cb); - NexeFileWasRenamed(PP_OK); + if (cache_identity_ != "") { + pp::CompletionCallback cb = + callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasRenamed); + nexe_file_->Rename(cache_identity_, cb); + } else { + // For now tolerate bitcode that is missing a cache identity. + PLUGIN_PRINTF(("PnaclCoordinator -- WARNING: missing cache identity," + " not caching.\n")); + NexeFileWasRenamed(PP_OK); + } } void PnaclCoordinator::NexeFileWasRenamed(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasRenamed (pp_error=%" NACL_PRId32")\n", pp_error)); + // NOTE: if the file already existed, it looks like the rename will + // happily succeed. However, we should add a test for this. if (pp_error != PP_OK) { - ReportPpapiError(pp_error); + ReportPpapiError(pp_error, "Failed to place cached bitcode translation."); return; } + nexe_file_->FinishRename(); // Open the nexe temporary file for reading. pp::CompletionCallback cb = callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); @@ -555,7 +605,7 @@ void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::NexeReadDidOpen (pp_error=%" NACL_PRId32")\n", pp_error)); if (pp_error != PP_OK) { - ReportPpapiError(pp_error); + ReportPpapiError(pp_error, "Failed to open translated nexe."); return; } // Transfer ownership of the nexe wrapper to the coordinator. @@ -612,8 +662,26 @@ void PnaclCoordinator::DirectoryWasCreated(int32_t pp_error) { ReportPpapiError(pp_error, "directory creation/check failed."); return; } - // Create the object file pair for connecting llc and ld. - obj_file_.reset(new LocalTempFile(plugin_, file_system_.get(), this)); + if (cache_identity_ != "") { + nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), + cache_identity_)); + pp::CompletionCallback cb = + callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen); + nexe_file_->OpenRead(cb); + } else { + // For now, tolerate lack of cache identity... + CachedFileDidOpen(PP_ERROR_FAILED); + } +} + +void PnaclCoordinator::CachedFileDidOpen(int32_t pp_error) { + + if (pp_error == PP_OK) { + NexeReadDidOpen(PP_OK); + return; + } + + obj_file_.reset(new LocalTempFile(plugin_, file_system_.get())); pp::CompletionCallback cb = callback_factory_.NewCallback(&PnaclCoordinator::ObjectWriteDidOpen); obj_file_->OpenWrite(cb); @@ -639,7 +707,7 @@ void PnaclCoordinator::ObjectReadDidOpen(int32_t pp_error) { return; } // Create the nexe file for connecting ld and sel_ldr. - nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), this)); + nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get())); pp::CompletionCallback cb = callback_factory_.NewCallback(&PnaclCoordinator::NexeWriteDidOpen); nexe_file_->OpenWrite(cb); diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h index b6ed522..af1fd0c 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h @@ -46,7 +46,7 @@ class PnaclCoordinator; // written by: llc (passed in explicitly through SRPC) // read by: ld (returned via lookup service from SRPC) // PnaclCoordinator::nexe_file_: -// written by: lc (passed in explicitly through SRPC) +// written by: ld (passed in explicitly through SRPC) // read by: sel_ldr (passed in explicitly to command channel) // @@ -57,9 +57,13 @@ class PnaclCoordinator; // for the file are opened. class LocalTempFile { public: + // Create a LocalTempFile with a random name. + LocalTempFile(Plugin* plugin, + pp::FileSystem* file_system); + // Create a LocalTempFile with a specific filename. LocalTempFile(Plugin* plugin, pp::FileSystem* file_system, - PnaclCoordinator* coordinator); + const nacl::string& filename); ~LocalTempFile(); // Opens a writeable file IO object and descriptor referring to the file. void OpenWrite(const pp::CompletionCallback& cb); @@ -72,6 +76,7 @@ class LocalTempFile { // Renames the temporary file. void Rename(const nacl::string& new_name, const pp::CompletionCallback& cb); + void FinishRename(); // Accessors. // The nacl::DescWrapper* for the writeable version of the file. @@ -93,6 +98,8 @@ class LocalTempFile { private: NACL_DISALLOW_COPY_AND_ASSIGN(LocalTempFile); + void Initialize(); + // Gets the POSIX file descriptor for a resource. int32_t GetFD(int32_t pp_error, const pp::Resource& resource, @@ -106,11 +113,12 @@ class LocalTempFile { Plugin* plugin_; pp::FileSystem* file_system_; - PnaclCoordinator* coordinator_; const PPB_FileIOTrusted* file_io_trusted_; pp::CompletionCallbackFactory<LocalTempFile> callback_factory_; nacl::string filename_; nacl::scoped_ptr<pp::FileRef> file_ref_; + // Temporarily holds the previous file ref during a rename operation. + nacl::scoped_ptr<pp::FileRef> old_ref_; // The PPAPI and wrapper state for the writeable file. nacl::scoped_ptr<pp::FileIO> write_io_; nacl::scoped_ptr<nacl::DescWrapper> write_wrapper_; @@ -176,6 +184,9 @@ class PnaclRefCount { // Complete when FileSystemDidOpen is invoked. // CREATED_PNACL_TEMP_DIRECTORY // Complete when DirectoryWasCreated is invoked. +// CACHED_FILE_OPEN +// Complete with success if cached version is available and jump to end. +// Otherwise, proceed with usual pipeline of translation. // OPEN_TMP_WRITE_FOR_LLC_TO_LD_COMMUNICATION // Complete when ObjectWriteDidOpen is invoked. // OPEN_TMP_READ_FOR_LLC_TO_LD_COMMUNICATION @@ -206,6 +217,7 @@ class PnaclCoordinator { static PnaclCoordinator* BitcodeToNative( Plugin* plugin, const nacl::string& pexe_url, + const nacl::string& cache_identity, const pp::CompletionCallback& translate_notify_callback); // Call this to take ownership of the FD of the translated nexe after @@ -234,6 +246,7 @@ class PnaclCoordinator { // Therefore the constructor is private. PnaclCoordinator(Plugin* plugin, const nacl::string& pexe_url, + const nacl::string& cache_identity, const pp::CompletionCallback& translate_notify_callback); // Callback for when llc and ld have been downloaded. @@ -246,6 +259,8 @@ class PnaclCoordinator { void FileSystemDidOpen(int32_t pp_error); // Invoked after we are sure the PNaCl temporary directory exists. void DirectoryWasCreated(int32_t pp_error); + // Invoked after we have checked the PNaCl cache for a translated version. + void CachedFileDidOpen(int32_t pp_error); // Invoked when the write descriptor for obj_file_ is created. void ObjectWriteDidOpen(int32_t pp_error); // Invoked when the read descriptor for obj_file_ is created. @@ -323,6 +338,8 @@ class PnaclCoordinator { // The URL for the pexe file. nacl::string pexe_url_; + // Optional cache identity for translation caching. + nacl::string cache_identity_; // Borrowed reference which must outlive the thread. nacl::scoped_ptr<nacl::DescWrapper> pexe_wrapper_; // Object file, produced by the translator and consumed by the linker. diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc index 972734c..7ac2792 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc @@ -247,7 +247,8 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n"); std::string mapped_url; - if (!manifest_->ResolveKey(p->url, &mapped_url, + std::string cache_identity; + if (!manifest_->ResolveKey(p->url, &mapped_url, &cache_identity, p->error_info, &p->pnacl_translate)) { NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n"); // Failed, and error_info has the details on what happened. Wake @@ -301,6 +302,7 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation( pnacl_coordinator_.reset( PnaclCoordinator::BitcodeToNative(plugin_, mapped_url, + cache_identity, translate_callback)); } // p is deleted automatically |