diff options
15 files changed, 84 insertions, 1118 deletions
diff --git a/chrome/test/nacl/nacl_browsertest.cc b/chrome/test/nacl/nacl_browsertest.cc index 2cad78a..eec3853 100644 --- a/chrome/test/nacl/nacl_browsertest.cc +++ b/chrome/test/nacl/nacl_browsertest.cc @@ -25,16 +25,6 @@ NACL_BROWSER_TEST_F(NaClBrowserTest, SimpleLoad, { RunLoadTest(FILE_PATH_LITERAL("nacl_load_test.html")); }) -IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclWithOldCache, - MAYBE_PNACL(SimpleLoad)) { - RunLoadTest(FILE_PATH_LITERAL("nacl_load_test.html")); -} - -IN_PROC_BROWSER_TEST_F(NaClBrowserTestPnaclWithOldCache, - MAYBE_PNACL(PnaclErrorHandling)) { - RunNaClIntegrationTest(FILE_PATH_LITERAL("pnacl_error_handling.html")); -} - NACL_BROWSER_TEST_F(NaClBrowserTest, ExitStatus0, { RunNaClIntegrationTest(FILE_PATH_LITERAL( "pm_exit_status_test.html?trigger=exit0&expected_exit=0")); diff --git a/chrome/test/nacl/nacl_browsertest_util.cc b/chrome/test/nacl/nacl_browsertest_util.cc index ace7305..d33a15f 100644 --- a/chrome/test/nacl/nacl_browsertest_util.cc +++ b/chrome/test/nacl/nacl_browsertest_util.cc @@ -6,7 +6,6 @@ #include <stdlib.h> #include "base/command_line.h" -#include "base/environment.h" #include "base/json/json_reader.h" #include "base/path_service.h" #include "base/values.h" @@ -319,11 +318,6 @@ void NaClBrowserTestPnaclDisabled::SetUpCommandLine(CommandLine* command_line) { command_line->AppendSwitch(switches::kDisablePnacl); } -NaClBrowserTestPnaclWithOldCache::NaClBrowserTestPnaclWithOldCache() { - scoped_ptr<base::Environment> env(base::Environment::Create()); - env->SetVar("PNACL_USE_OLD_CACHE", "true"); -} - base::FilePath::StringType NaClBrowserTestStatic::Variant() { return FILE_PATH_LITERAL("static"); } diff --git a/chrome/test/nacl/nacl_browsertest_util.h b/chrome/test/nacl/nacl_browsertest_util.h index 27e638b..cff0970 100644 --- a/chrome/test/nacl/nacl_browsertest_util.h +++ b/chrome/test/nacl/nacl_browsertest_util.h @@ -136,13 +136,6 @@ class NaClBrowserTestPnaclDisabled : public NaClBrowserTestBase { virtual bool IsPnaclDisabled() OVERRIDE; }; -// Temporary class for running tests with the old cache enabled. Once all the -// pieces are stable and the old code is gone, this will go away. -class NaClBrowserTestPnaclWithOldCache : public NaClBrowserTestPnacl { - public: - NaClBrowserTestPnaclWithOldCache(); -}; - // A NaCl browser test only using static files. class NaClBrowserTestStatic : public NaClBrowserTestBase { public: diff --git a/ppapi/native_client/src/trusted/plugin/local_temp_file.cc b/ppapi/native_client/src/trusted/plugin/local_temp_file.cc deleted file mode 100644 index 15917e7..0000000 --- a/ppapi/native_client/src/trusted/plugin/local_temp_file.cc +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ppapi/native_client/src/trusted/plugin/local_temp_file.h" - -#include "native_client/src/include/portability_io.h" -#include "native_client/src/shared/platform/nacl_check.h" - -#include "ppapi/c/ppb_file_io.h" -#include "ppapi/cpp/file_io.h" -#include "ppapi/cpp/file_ref.h" -#include "ppapi/cpp/file_system.h" - -#include "ppapi/native_client/src/trusted/plugin/plugin.h" -#include "ppapi/native_client/src/trusted/plugin/utility.h" - -////////////////////////////////////////////////////////////////////// -// Local temporary file access. -////////////////////////////////////////////////////////////////////// -namespace plugin { - -namespace { -nacl::string Random32CharHexString(struct NaClDescRng* rng) { - struct NaClDesc* desc = reinterpret_cast<struct NaClDesc*>(rng); - const struct NaClDescVtbl* vtbl = - reinterpret_cast<const struct NaClDescVtbl*>(desc->base.vtbl); - - nacl::string hex_string; - const int32_t kTempFileNameWords = 4; - for (int32_t i = 0; i < kTempFileNameWords; ++i) { - int32_t num; - CHECK(sizeof num == vtbl->Read(desc, - reinterpret_cast<char*>(&num), - sizeof num)); - char frag[16]; - SNPRINTF(frag, sizeof frag, "%08x", num); - hex_string += nacl::string(frag); - } - return hex_string; -} - -// Some constants for LocalTempFile::GetFD readability. -const bool kReadOnly = false; -const bool kWriteable = true; -} // namespace - -uint32_t LocalTempFile::next_identifier = 0; - -LocalTempFile::LocalTempFile(Plugin* plugin, - pp::FileSystem* file_system, - const nacl::string &base_dir) - : plugin_(plugin), - file_system_(file_system), - base_dir_(base_dir) { - 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, - const nacl::string &base_dir, - const nacl::string &filename) - : plugin_(plugin), - file_system_(file_system), - base_dir_(base_dir), - filename_(base_dir + "/" + filename) { - PLUGIN_PRINTF(("LocalTempFile::LocalTempFile (plugin=%p, " - "file_system=%p, filename=%s)\n", - static_cast<void*>(plugin), static_cast<void*>(file_system), - 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); - CHECK(NaClDescRngCtor(rng_desc_)); - file_io_trusted_ = static_cast<const PPB_FileIOTrusted*>( - pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE)); - ++next_identifier; - SNPRINTF(reinterpret_cast<char *>(identifier_), sizeof identifier_, - "%" NACL_PRIu32, next_identifier); -} - -LocalTempFile::~LocalTempFile() { - PLUGIN_PRINTF(("LocalTempFile::~LocalTempFile\n")); - NaClDescUnref(reinterpret_cast<NaClDesc*>(rng_desc_)); -} - -void LocalTempFile::OpenWrite(const pp::CompletionCallback& cb) { - done_callback_ = cb; - // If we don't already have a filename, generate one. - if (filename_ == "") { - // Get a random temp file name. - filename_ = base_dir_ + "/" + Random32CharHexString(rng_desc_); - // Remember the ref used to open for writing and reading. - file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str())); - } - PLUGIN_PRINTF(("LocalTempFile::OpenWrite: %s\n", filename_.c_str())); - // Open the writeable file. - write_io_.reset(new pp::FileIO(plugin_)); - pp::CompletionCallback open_write_cb = - callback_factory_.NewCallback(&LocalTempFile::WriteFileDidOpen); - write_io_->Open(*file_ref_, - PP_FILEOPENFLAG_WRITE | - PP_FILEOPENFLAG_CREATE | - PP_FILEOPENFLAG_EXCLUSIVE, - open_write_cb); -} - -int32_t LocalTempFile::GetFD(int32_t pp_error, - const pp::Resource& resource, - bool is_writable) { - PLUGIN_PRINTF(("LocalTempFile::GetFD (pp_error=%" NACL_PRId32 - ", is_writable=%d)\n", pp_error, is_writable)); - if (pp_error != PP_OK) { - PLUGIN_PRINTF(("LocalTempFile::GetFD pp_error != PP_OK\n")); - return -1; - } - int32_t file_desc = - file_io_trusted_->GetOSFileDescriptor(resource.pp_resource()); -#if NACL_WINDOWS - // Convert the Windows HANDLE from Pepper to a POSIX file descriptor. - int32_t open_flags = ((is_writable ? _O_RDWR : _O_RDONLY) | _O_BINARY); - int32_t posix_desc = _open_osfhandle(file_desc, open_flags); - if (posix_desc == -1) { - // Close the Windows HANDLE if it can't be converted. - CloseHandle(reinterpret_cast<HANDLE>(file_desc)); - PLUGIN_PRINTF(("LocalTempFile::GetFD _open_osfhandle failed.\n")); - return NACL_NO_FILE_DESC; - } - file_desc = posix_desc; -#endif - int32_t file_desc_ok_to_close = DUP(file_desc); - if (file_desc_ok_to_close == NACL_NO_FILE_DESC) { - PLUGIN_PRINTF(("LocalTempFile::GetFD dup failed.\n")); - return -1; - } - return file_desc_ok_to_close; -} - -void LocalTempFile::WriteFileDidOpen(int32_t pp_error) { - PLUGIN_PRINTF(("LocalTempFile::WriteFileDidOpen (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error == PP_ERROR_FILEEXISTS) { - // Filenames clashed, retry. - 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) { - 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_)); - core->CallOnMainThread(0, done_callback_, PP_OK); -} - -void LocalTempFile::OpenRead(const pp::CompletionCallback& cb) { - PLUGIN_PRINTF(("LocalTempFile::OpenRead: %s\n", filename_.c_str())); - done_callback_ = cb; - // Open the read only file. - read_io_.reset(new pp::FileIO(plugin_)); - pp::CompletionCallback open_read_cb = - callback_factory_.NewCallback(&LocalTempFile::ReadFileDidOpen); - read_io_->Open(*file_ref_, PP_FILEOPENFLAG_READ, open_read_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) { - core->CallOnMainThread(0, done_callback_, PP_ERROR_FAILED); - return; - } - read_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); - core->CallOnMainThread(0, done_callback_, PP_OK); -} - -void LocalTempFile::Close(const pp::CompletionCallback& cb) { - PLUGIN_PRINTF(("LocalTempFile::Close: %s\n", filename_.c_str())); - // Close the open DescWrappers and FileIOs. - if (write_io_.get() != NULL) { - write_io_->Close(); - } - write_wrapper_.reset(NULL); - write_io_.reset(NULL); - if (read_io_.get() != NULL) { - read_io_->Close(); - } - read_wrapper_.reset(NULL); - read_io_.reset(NULL); - // Run the client's completion callback. - pp::Core* core = pp::Module::Get()->core(); - core->CallOnMainThread(0, cb, PP_OK); -} - -void LocalTempFile::Delete(const pp::CompletionCallback& cb) { - PLUGIN_PRINTF(("LocalTempFile::Delete: %s\n", filename_.c_str())); - file_ref_->Delete(cb); -} - -void LocalTempFile::Rename(const nacl::string& new_name, - const pp::CompletionCallback& cb) { - // Rename the temporary file. - filename_ = base_dir_ + "/" + new_name; - PLUGIN_PRINTF(("LocalTempFile::Rename %s to %s\n", - file_ref_->GetName().AsString().c_str(), - 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); -} - -} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/local_temp_file.h b/ppapi/native_client/src/trusted/plugin/local_temp_file.h deleted file mode 100644 index 51d2095..0000000 --- a/ppapi/native_client/src/trusted/plugin/local_temp_file.h +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_LOCAL_TEMP_FILE_H_ -#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_LOCAL_TEMP_FILE_H_ - -#include "native_client/src/include/nacl_macros.h" -#include "native_client/src/include/nacl_string.h" -#include "native_client/src/trusted/desc/nacl_desc_rng.h" -#include "native_client/src/trusted/desc/nacl_desc_wrapper.h" - -#include "ppapi/c/trusted/ppb_file_io_trusted.h" -#include "ppapi/utility/completion_callback_factory.h" - -namespace pp { -class CompletionCallback; -class FileIO; -class FileRef; -class FileSystem; -} - -namespace plugin { - -class Plugin; - -// Translation creates two temporary files. The first temporary file holds -// the object file created by llc. The second holds the nexe produced by -// the linker. Both of these temporary files are used to both write and -// read according to the following matrix: -// -// PnaclCoordinator::obj_file_: -// written by: llc (passed in explicitly through SRPC) -// read by: ld (returned via lookup service from SRPC) -// PnaclCoordinator::nexe_file_: -// written by: ld (passed in explicitly through SRPC) -// read by: sel_ldr (passed in explicitly to command channel) -// - -// LocalTempFile represents a file used as a temporary between stages in -// translation. It is created in the local temporary file system of the page -// being processed. The name of the temporary file is a random 32-character -// hex string. Because both reading and writing are necessary, two I/O objects -// for the file are opened. -class LocalTempFile { - public: - // Create a LocalTempFile with a random name. - LocalTempFile(Plugin* plugin, - pp::FileSystem* file_system, - const nacl::string& base_dir); - // Create a LocalTempFile with a specific filename. - LocalTempFile(Plugin* plugin, - pp::FileSystem* file_system, - const nacl::string& base_dir, - const nacl::string& filename); - ~LocalTempFile(); - // Opens a writeable file IO object and descriptor referring to the file. - void OpenWrite(const pp::CompletionCallback& cb); - // Opens a read only file IO object and descriptor referring to the file. - void OpenRead(const pp::CompletionCallback& cb); - // Closes the open descriptors. - void Close(const pp::CompletionCallback& cb); - // Deletes the temporary file. - void Delete(const pp::CompletionCallback& cb); - // 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. - nacl::DescWrapper* write_wrapper() { return write_wrapper_.get(); } - nacl::DescWrapper* release_write_wrapper() { - return write_wrapper_.release(); - } - // The nacl::DescWrapper* for the read-only version of the file. - nacl::DescWrapper* read_wrapper() { return read_wrapper_.get(); } - nacl::DescWrapper* release_read_wrapper() { - return read_wrapper_.release(); - } - // For quota management. - const nacl::string identifier() const { - return nacl::string(reinterpret_cast<const char*>(identifier_)); - } - pp::FileIO* write_file_io() const { return write_io_.get(); } - - 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, - bool is_writable); - // Called when the writable file IO was opened. - void WriteFileDidOpen(int32_t pp_error); - // Called when the readable file IO was opened. - void ReadFileDidOpen(int32_t pp_error); - // Completes the close operation after quota update. - void CloseContinuation(int32_t pp_error); - - Plugin* plugin_; - pp::FileSystem* file_system_; - const PPB_FileIOTrusted* file_io_trusted_; - pp::CompletionCallbackFactory<LocalTempFile> callback_factory_; - nacl::string base_dir_; - 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_; - // The PPAPI and wrapper state for the read-only file. - nacl::scoped_ptr<pp::FileIO> read_io_; - nacl::scoped_ptr<nacl::DescWrapper> read_wrapper_; - // The callback invoked when both file I/O objects are created. - pp::CompletionCallback done_callback_; - // Random number generator used to create filenames. - struct NaClDescRng *rng_desc_; - // An identifier string used for quota request processing. The quota - // interface needs a string that is unique per sel_ldr instance only, so - // the identifiers can be reused between runs of the translator, start-ups of - // the browser, etc. - uint8_t identifier_[16]; - // A counter to dole out unique identifiers. - static uint32_t next_identifier; -}; - -} // namespace plugin - -#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_LOCAL_TEMP_FILE_H_ diff --git a/ppapi/native_client/src/trusted/plugin/module_ppapi.cc b/ppapi/native_client/src/trusted/plugin/module_ppapi.cc index f78bbf3..b73a1a3 100644 --- a/ppapi/native_client/src/trusted/plugin/module_ppapi.cc +++ b/ppapi/native_client/src/trusted/plugin/module_ppapi.cc @@ -5,10 +5,10 @@ */ #include "native_client/src/shared/imc/nacl_imc_c.h" +#include "native_client/src/shared/platform/nacl_secure_random.h" #include "native_client/src/shared/platform/nacl_time.h" #include "native_client/src/trusted/desc/nrd_all_modules.h" - #include "ppapi/native_client/src/trusted/plugin/module_ppapi.h" #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h" #include "ppapi/native_client/src/trusted/plugin/plugin.h" diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gypi b/ppapi/native_client/src/trusted/plugin/plugin.gypi index 1357a37..7f3bff4 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.gypi +++ b/ppapi/native_client/src/trusted/plugin/plugin.gypi @@ -9,7 +9,6 @@ 'file_downloader.cc', 'file_utils.cc', 'json_manifest.cc', - 'local_temp_file.cc', 'module_ppapi.cc', 'nacl_http_response_headers.cc', 'nacl_subprocess.cc', diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index 10311a9..1a29c70 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -14,11 +14,8 @@ #include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_errors.h" -#include "ppapi/c/ppb_file_io.h" #include "ppapi/c/private/ppb_uma_private.h" -#include "ppapi/cpp/file_io.h" -#include "ppapi/native_client/src/trusted/plugin/local_temp_file.h" #include "ppapi/native_client/src/trusted/plugin/manifest.h" #include "ppapi/native_client/src/trusted/plugin/nacl_http_response_headers.h" #include "ppapi/native_client/src/trusted/plugin/plugin.h" @@ -27,11 +24,6 @@ #include "ppapi/native_client/src/trusted/plugin/service_runtime.h" #include "ppapi/native_client/src/trusted/plugin/temporary_file.h" -namespace { -const char kPnaclTempDir[] = "/.pnacl"; -const uint32_t kCopyBufSize = 512 << 10; -} - namespace plugin { ////////////////////////////////////////////////////////////////////// @@ -259,13 +251,10 @@ PnaclCoordinator::PnaclCoordinator( : translate_finish_error_(PP_OK), plugin_(plugin), translate_notify_callback_(translate_notify_callback), - file_system_(new pp::FileSystem(plugin, PP_FILESYSTEMTYPE_LOCALTEMPORARY)), manifest_(new PnaclManifest()), pexe_url_(pexe_url), pnacl_options_(pnacl_options), - use_new_cache_(true), is_cache_hit_(PP_FALSE), - nexe_handle_(PP_kInvalidFileHandle), error_already_reported_(false), off_the_record_(false), pnacl_init_time_(0), @@ -275,10 +264,6 @@ PnaclCoordinator::PnaclCoordinator( PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", static_cast<void*>(this), static_cast<void*>(plugin))); callback_factory_.Initialize(this); - if (getenv("PNACL_USE_OLD_CACHE")) { - PLUGIN_PRINTF(("PnaclCoordinator using old translation cache\n")); - use_new_cache_ = false; - } } PnaclCoordinator::~PnaclCoordinator() { @@ -295,6 +280,11 @@ PnaclCoordinator::~PnaclCoordinator() { } } +nacl::DescWrapper* PnaclCoordinator::ReleaseTranslatedFD() { + DCHECK(temp_nexe_file_ != NULL); + return temp_nexe_file_->release_read_wrapper(); +} + void PnaclCoordinator::ReportNonPpapiError(enum PluginErrorCode err_code, const nacl::string& message) { error_info_.SetReport(err_code, message); @@ -339,11 +329,9 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) { // Bail out if there was an earlier error (e.g., pexe load failure), // or if there is an error from the translation thread. if (translate_finish_error_ != PP_OK || pp_error != PP_OK) { - if (use_new_cache_) { - plugin_->nacl_interface()->ReportTranslationFinished( - plugin_->pp_instance(), - PP_FALSE); - } + plugin_->nacl_interface()->ReportTranslationFinished( + plugin_->pp_instance(), + PP_FALSE); ExitWithError(); return; } @@ -388,242 +376,6 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) { HistogramRatio("NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size); } - // The nexe is written to the temp_nexe_file_. We must Reset() the file - // pointer to be able to read it again from the beginning. - temp_nexe_file_->Reset(); - - if (use_new_cache_) { - // Report to the browser that translation finished. The browser will take - // care of caching. - plugin_->nacl_interface()->ReportTranslationFinished( - plugin_->pp_instance(), PP_TRUE); - - // These can maybe move up with the rest of the UMA stats when we remove - // the old cache code - int64_t total_time = NaClGetTimeOfDayMicroseconds() - pnacl_init_time_; - HistogramTime("NaCl.Perf.PNaClLoadTime.TotalUncachedTime", - total_time / NACL_MICROS_PER_MILLI); - HistogramKBPerSec("NaCl.Perf.PNaClLoadTime.TotalUncachedKBPerSec", - pexe_size_ / 1024.0, - total_time / 1000000.0); - NexeReadDidOpen(PP_OK); - return; - } - if (pnacl_options_.HasCacheKey() && cached_nexe_file_ != NULL) { - // We are using a cache, but had a cache miss, which is why we did the - // translation. Reset cached_nexe_file_ to have a random name, - // for scratch purposes, before renaming to the final cache_identity. - cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), - nacl::string(kPnaclTempDir))); - pp::CompletionCallback cb = callback_factory_.NewCallback( - &PnaclCoordinator::CachedNexeOpenedForWrite); - cached_nexe_file_->OpenWrite(cb); - } else { - // For now, tolerate bitcode that is missing a cache identity, and - // tolerate the lack of caching in incognito mode. - PLUGIN_PRINTF(("PnaclCoordinator -- not caching.\n")); - NexeReadDidOpen(PP_OK); - } -} - -void PnaclCoordinator::CachedNexeOpenedForWrite(int32_t pp_error) { - if (pp_error != PP_OK) { - if (pp_error == PP_ERROR_NOACCESS) { - ReportPpapiError( - ERROR_PNACL_CACHE_FILEOPEN_NOACCESS, - pp_error, - "PNaCl translation cache failed to open file for write " - "(no access)."); - return; - } - if (pp_error == PP_ERROR_NOQUOTA) { - ReportPpapiError( - ERROR_PNACL_CACHE_FILEOPEN_NOQUOTA, - pp_error, - "PNaCl translation cache failed to open file for write " - "(no quota)."); - return; - } - if (pp_error == PP_ERROR_NOSPACE) { - ReportPpapiError( - ERROR_PNACL_CACHE_FILEOPEN_NOSPACE, - pp_error, - "PNaCl translation cache failed to open file for write " - "(no space)."); - return; - } - if (pp_error == PP_ERROR_NOTAFILE) { - ReportPpapiError(ERROR_PNACL_CACHE_FILEOPEN_NOTAFILE, - pp_error, - "PNaCl translation cache failed to open file for write." - " File already exists as a directory."); - return; - } - ReportPpapiError(ERROR_PNACL_CACHE_FILEOPEN_OTHER, - pp_error, - "PNaCl translation cache failed to open file for write."); - return; - } - - // Copy the contents from temp_nexe_file_ -> cached_nexe_file_, - // then rename the cached_nexe_file_ file to the cache id. - int64_t cur_offset = 0; - nacl::DescWrapper* read_wrapper = temp_nexe_file_->read_wrapper(); - char buf[kCopyBufSize]; - int32_t num_read = - nacl::assert_cast<int32_t>(read_wrapper->Read(buf, sizeof buf)); - // Hit EOF or something. - if (num_read == 0) { - NexeWasCopiedToCache(PP_OK); - return; - } - if (num_read < 0) { - PLUGIN_PRINTF(("PnaclCoordinator::CachedNexeOpenedForWrite read failed " - "(error=%" NACL_PRId32 ")\n", num_read)); - NexeWasCopiedToCache(PP_ERROR_FAILED); - return; - } - pp::CompletionCallback cb = callback_factory_.NewCallback( - &PnaclCoordinator::DidCopyNexeToCachePartial, num_read, cur_offset); - cached_nexe_file_->write_file_io()->Write(cur_offset, buf, num_read, cb); -} - -void PnaclCoordinator::DidCopyNexeToCachePartial(int32_t pp_error, - int32_t num_read_prev, - int64_t cur_offset) { - PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial " - "(pp_error=%" NACL_PRId32 ", num_read_prev=%" NACL_PRId32 - ", cur_offset=%" NACL_PRId64 ").\n", - pp_error, num_read_prev, cur_offset)); - // Assume we are done. - if (pp_error == PP_OK) { - NexeWasCopiedToCache(PP_OK); - return; - } - if (pp_error < PP_OK) { - PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial failed (err=%" - NACL_PRId32 ")\n", pp_error)); - NexeWasCopiedToCache(pp_error); - return; - } - - // Check if we wrote as much as we read. - nacl::DescWrapper* read_wrapper = temp_nexe_file_->read_wrapper(); - if (pp_error != num_read_prev) { - PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial partial " - "write (bytes_written=%" NACL_PRId32 " vs " - "read=%" NACL_PRId32 ")\n", pp_error, num_read_prev)); - CHECK(pp_error < num_read_prev); - // Seek back to re-read the bytes that were not written. - nacl_off64_t seek_result = - read_wrapper->Seek(pp_error - num_read_prev, SEEK_CUR); - if (seek_result < 0) { - PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial seek failed " - "(err=%" NACL_PRId64 ")\n", seek_result)); - NexeWasCopiedToCache(PP_ERROR_FAILED); - return; - } - } - - int64_t next_offset = cur_offset + pp_error; - char buf[kCopyBufSize]; - int32_t num_read = - nacl::assert_cast<int32_t>(read_wrapper->Read(buf, sizeof buf)); - PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial read (bytes=%" - NACL_PRId32 ")\n", num_read)); - // Hit EOF or something. - if (num_read == 0) { - NexeWasCopiedToCache(PP_OK); - return; - } - if (num_read < 0) { - PLUGIN_PRINTF(("PnaclCoordinator::DidCopyNexeToCachePartial read failed " - "(error=%" NACL_PRId32 ")\n", num_read)); - NexeWasCopiedToCache(PP_ERROR_FAILED); - return; - } - pp::CompletionCallback cb = callback_factory_.NewCallback( - &PnaclCoordinator::DidCopyNexeToCachePartial, num_read, next_offset); - PLUGIN_PRINTF(("PnaclCoordinator::CopyNexeToCache Writing (" - "bytes=%" NACL_PRId32 ", buf=%p, file_io=%p)\n", num_read, buf, - cached_nexe_file_->write_file_io())); - cached_nexe_file_->write_file_io()->Write(next_offset, buf, num_read, cb); -} - -void PnaclCoordinator::NexeWasCopiedToCache(int32_t pp_error) { - if (pp_error != PP_OK) { - // Try to delete the partially written not-yet-committed cache file before - // returning. We pass the current pp_error along so that it can be reported - // before returning. - pp::CompletionCallback cb = callback_factory_.NewCallback( - &PnaclCoordinator::CorruptCacheFileWasDeleted, pp_error); - cached_nexe_file_->Delete(cb); - return; - } - // Rename the cached_nexe_file_ file to the cache id, to finalize. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasRenamed); - cached_nexe_file_->Rename(pnacl_options_.GetCacheKey(), cb); -} - -void PnaclCoordinator::CorruptCacheFileWasDeleted(int32_t delete_pp_error, - int32_t orig_pp_error) { - if (delete_pp_error != PP_OK) { - // The cache file was certainly already opened by the time we tried - // to write to it, so it should certainly be deletable. - PLUGIN_PRINTF(("PnaclCoordinator::CorruptCacheFileWasDeleted " - "delete failed with pp_error=%" NACL_PRId32 "\n", - delete_pp_error)); - // fall through and report the original error. - } - // Report the original error that caused us to consider the - // cache file corrupted. - if (orig_pp_error == PP_ERROR_NOQUOTA) { - ReportPpapiError(ERROR_PNACL_CACHE_FINALIZE_COPY_NOQUOTA, - orig_pp_error, - "Failed to copy translated nexe to cache (no quota)."); - return; - } - if (orig_pp_error == PP_ERROR_NOSPACE) { - ReportPpapiError(ERROR_PNACL_CACHE_FINALIZE_COPY_NOSPACE, - orig_pp_error, - "Failed to copy translated nexe to cache (no space)."); - return; - } - ReportPpapiError(ERROR_PNACL_CACHE_FINALIZE_COPY_OTHER, - orig_pp_error, - "Failed to copy translated nexe to cache."); - return; -} - -void PnaclCoordinator::NexeFileWasRenamed(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasRenamed (pp_error=%" - NACL_PRId32 ")\n", pp_error)); - if (pp_error != PP_OK) { - if (pp_error == PP_ERROR_NOACCESS) { - ReportPpapiError(ERROR_PNACL_CACHE_FINALIZE_RENAME_NOACCESS, - pp_error, - "Failed to finalize cached translation (no access)."); - return; - } else if (pp_error != PP_ERROR_FILEEXISTS) { - ReportPpapiError(ERROR_PNACL_CACHE_FINALIZE_RENAME_OTHER, - pp_error, - "Failed to finalize cached translation."); - return; - } else { // pp_error == PP_ERROR_FILEEXISTS. - // NOTE: if the file already existed, it looks like the rename will - // happily succeed. However, we should add a test for this. - // Could be a hash collision, or it could also be two tabs racing to - // translate the same pexe. We may want UMA stats to know if this happens. - // For now, assume that it is a race and try to continue. - // If there is truly a corrupted file, then sel_ldr should prevent the - // file from loading due to the file size not matching the ELF header. - PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasRenamed file existed\n")); - } - } - - cached_nexe_file_->FinishRename(); - int64_t total_time = NaClGetTimeOfDayMicroseconds() - pnacl_init_time_; HistogramTime("NaCl.Perf.PNaClLoadTime.TotalUncachedTime", total_time / NACL_MICROS_PER_MILLI); @@ -631,10 +383,16 @@ void PnaclCoordinator::NexeFileWasRenamed(int32_t pp_error) { pexe_size_ / 1024.0, total_time / 1000000.0); - // Open the cache file for reading. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); - cached_nexe_file_->OpenRead(cb); + // The nexe is written to the temp_nexe_file_. We must Reset() the file + // pointer to be able to read it again from the beginning. + temp_nexe_file_->Reset(); + + // Report to the browser that translation finished. The browser will take + // care of storing the nexe in the cache. + plugin_->nacl_interface()->ReportTranslationFinished( + plugin_->pp_instance(), PP_TRUE); + + NexeReadDidOpen(PP_OK); } void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { @@ -659,12 +417,6 @@ void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { return; } - // Transfer ownership of cache/temp file's wrapper to the coordinator. - if (cached_nexe_file_ != NULL) { - translated_fd_.reset(cached_nexe_file_->release_read_wrapper()); - } else { - translated_fd_.reset(temp_nexe_file_->release_read_wrapper()); - } translate_notify_callback_.Run(pp_error); } @@ -710,97 +462,6 @@ void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { return; } - if (!off_the_record_) { - if (use_new_cache_) { - OpenBitcodeStream(); - } else { - // Open the local temporary FS to see if we get a hit in the cache. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::FileSystemDidOpen); - int32_t open_error = file_system_->Open(0, cb); - if (open_error != PP_OK_COMPLETIONPENDING) { - // At this point, no async request has kicked off to check for - // permissions, space, etc., so the only error that can be detected - // now is that an open() is already in progress (or a really terrible - // error). - if (pp_error == PP_ERROR_INPROGRESS) { - ReportPpapiError( - ERROR_PNACL_CACHE_OPEN_INPROGRESS, - pp_error, - "File system for PNaCl translation cache failed to open " - "(in progress)."); - return; - } - ReportPpapiError( - ERROR_PNACL_CACHE_OPEN_OTHER, - pp_error, - "File system for PNaCl translation cache failed to open."); - } - } - } else { - // We don't have a cache, so do the non-cached codepath. - OpenBitcodeStream(); - } -} - -void PnaclCoordinator::FileSystemDidOpen(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::FileSystemDidOpen (pp_error=%" - NACL_PRId32 ")\n", pp_error)); - if (pp_error != PP_OK) { - if (pp_error == PP_ERROR_NOACCESS) { - ReportPpapiError( - ERROR_PNACL_CACHE_OPEN_NOACCESS, - pp_error, - "File system for PNaCl translation cache failed to open " - "(no access)."); - return; - } - if (pp_error == PP_ERROR_NOQUOTA) { - ReportPpapiError( - ERROR_PNACL_CACHE_OPEN_NOQUOTA, - pp_error, - "File system for PNaCl translation cache failed to open " - "(no quota)."); - return; - } - if (pp_error == PP_ERROR_NOSPACE) { - ReportPpapiError( - ERROR_PNACL_CACHE_OPEN_NOSPACE, - pp_error, - "File system for PNaCl translation cache failed to open " - "(no space)."); - return; - } - ReportPpapiError(ERROR_PNACL_CACHE_OPEN_OTHER, - pp_error, - "File system for PNaCl translation cache failed to open."); - } - dir_ref_.reset(new pp::FileRef(*file_system_, kPnaclTempDir)); - // Attempt to create the directory. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::DirectoryWasCreated); - dir_ref_->MakeDirectory(cb); -} - -void PnaclCoordinator::DirectoryWasCreated(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::DirectoryWasCreated (pp_error=%" - NACL_PRId32 ")\n", pp_error)); - if (pp_error != PP_ERROR_FILEEXISTS && pp_error != PP_OK) { - // Directory did not exist and could not be created. - if (pp_error == PP_ERROR_NOACCESS) { - ReportPpapiError( - ERROR_PNACL_CACHE_DIRECTORY_CREATE, - pp_error, - "PNaCl translation cache directory creation/check failed " - "(no access)."); - return; - } - ReportPpapiError( - ERROR_PNACL_CACHE_DIRECTORY_CREATE, - pp_error, - "PNaCl translation cache directory creation/check failed."); - return; - } OpenBitcodeStream(); } @@ -820,14 +481,6 @@ void PnaclCoordinator::OpenBitcodeStream() { "PnaclCoordinator: could not allocate translation thread."); return; } - if (!use_new_cache_) { - // We also want to open the object file now so the - // translator can start writing to it during streaming translation. - obj_file_.reset(new TempFile(plugin_)); - pp::CompletionCallback obj_cb = - callback_factory_.NewCallback(&PnaclCoordinator::ObjectFileDidOpen); - obj_file_->Open(obj_cb, true); - } pp::CompletionCallback cb = callback_factory_.NewCallback(&PnaclCoordinator::BitcodeStreamDidOpen); @@ -842,66 +495,38 @@ void PnaclCoordinator::OpenBitcodeStream() { void PnaclCoordinator::BitcodeStreamDidOpen(int32_t pp_error) { if (pp_error != PP_OK) { BitcodeStreamDidFinish(pp_error); - // In the new cache case, we have not spun up the translation process yet, - // so we need to call TranslateFinished here. - if (use_new_cache_) - TranslateFinished(pp_error); + // We have not spun up the translation process yet, so we need to call + // TranslateFinished here. + TranslateFinished(pp_error); return; } - if (!off_the_record_ || use_new_cache_) { - // Get the cache key and try to open an existing entry. - nacl::string headers = streaming_downloader_->GetResponseHeaders(); - NaClHttpResponseHeaders parser; - parser.Parse(headers); - nacl::string cache_validators = parser.GetCacheValidators(); - if (parser.CacheControlNoStore() || cache_validators.empty()) { - // We can't cache in this case. - pnacl_options_.set_cache_validators(""); - CachedFileDidOpen(PP_ERROR_FAILED); - return; - } else { - nacl::string url = streaming_downloader_->url(); - // For now, combine the cache_validators + the URL as the key. - // When we change the cache backend to be not-origin-specific - // we should send the URL separately, and check in the browser's - // RenderViewHost / SiteInstance's IsSameWebsite() to prevent - // people from forging the URL for a different origin. - pnacl_options_.set_cache_validators(cache_validators + url); - } - if (use_new_cache_) { - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::NexeFdDidOpen); - int32_t nexe_fd_err = - plugin_->nacl_interface()->GetNexeFd( - plugin_->pp_instance(), - streaming_downloader_->url().c_str(), - // TODO(dschuff): Get this value from the pnacl json file after it - // rolls in from NaCl. - 1, - pnacl_options_.opt_level(), - parser.GetHeader("last-modified").c_str(), - parser.GetHeader("etag").c_str(), - &is_cache_hit_, - &nexe_handle_, - cb.pp_completion_callback()); - if (nexe_fd_err < PP_OK_COMPLETIONPENDING) { - ReportPpapiError(ERROR_PNACL_CREATE_TEMP, nexe_fd_err, - nacl::string("Call to GetNexeFd failed")); - return; - } - } else { - cached_nexe_file_.reset(new LocalTempFile( - plugin_, file_system_.get(), - nacl::string(kPnaclTempDir), - pnacl_options_.GetCacheKey())); - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen); - cached_nexe_file_->OpenRead(cb); - } - } else { - // No cache case. - CachedFileDidOpen(PP_ERROR_FAILED); + // Get the cache key and try to open an existing entry. + nacl::string headers = streaming_downloader_->GetResponseHeaders(); + NaClHttpResponseHeaders parser; + parser.Parse(headers); + // TODO(dschuff): honor parser.CacheControlNoStore(). It wasn't handled in + // the new cache case before. + + temp_nexe_file_.reset(new TempFile(plugin_)); + pp::CompletionCallback cb = + callback_factory_.NewCallback(&PnaclCoordinator::NexeFdDidOpen); + int32_t nexe_fd_err = + plugin_->nacl_interface()->GetNexeFd( + plugin_->pp_instance(), + streaming_downloader_->url().c_str(), + // TODO(dschuff): Get this value from the pnacl json file after it + // rolls in from NaCl. + 1, + pnacl_options_.opt_level(), + parser.GetHeader("last-modified").c_str(), + parser.GetHeader("etag").c_str(), + &is_cache_hit_, + temp_nexe_file_->existing_handle(), + cb.pp_completion_callback()); + if (nexe_fd_err < PP_OK_COMPLETIONPENDING) { + ReportPpapiError(ERROR_PNACL_CREATE_TEMP, nexe_fd_err, + nacl::string("Call to GetNexeFd failed")); } } @@ -909,14 +534,14 @@ void PnaclCoordinator::NexeFdDidOpen(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::NexeFdDidOpen (pp_error=%" NACL_PRId32 ", hit=%d, handle=%d)\n", pp_error, is_cache_hit_ == PP_TRUE, - nexe_handle_)); + *temp_nexe_file_->existing_handle())); if (pp_error < PP_OK) { ReportPpapiError(ERROR_PNACL_CREATE_TEMP, pp_error, nacl::string("GetNexeFd failed")); return; } - temp_nexe_file_.reset(new TempFile(plugin_)); - if (!temp_nexe_file_->SetExistingFd(nexe_handle_)) { + + if (*temp_nexe_file_->existing_handle() == PP_kInvalidFileHandle) { ReportNonPpapiError( ERROR_PNACL_CREATE_TEMP, nacl::string( @@ -950,25 +575,6 @@ void PnaclCoordinator::NexeFdDidOpen(int32_t pp_error) { } } -void PnaclCoordinator::CachedFileDidOpen(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::CachedFileDidOpen (pp_error=%" - NACL_PRId32 ")\n", pp_error)); - if (pp_error == PP_OK) { - // Cache hit -- no need to stream the rest of the file. - streaming_downloader_.reset(NULL); - HistogramEnumerateTranslationCache(true); - NexeReadDidOpen(PP_OK); - return; - } - // Otherwise, the cache file is missing so we must translate. - HistogramEnumerateTranslationCache(false); - - // Continue streaming. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::BitcodeStreamDidFinish); - streaming_downloader_->FinishStreaming(cb); -} - void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%" NACL_PRId32 ")\n", pp_error)); @@ -989,11 +595,9 @@ void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ")."; error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); } - if (use_new_cache_) { - plugin_->nacl_interface()->ReportTranslationFinished( - plugin_->pp_instance(), - PP_FALSE); - } + plugin_->nacl_interface()->ReportTranslationFinished( + plugin_->pp_instance(), + PP_FALSE); translate_thread_->AbortSubprocesses(); } else { // Compare download completion pct (100% now), to compile completion pct. @@ -1068,19 +672,13 @@ void PnaclCoordinator::ObjectFileDidOpen(int32_t pp_error) { ReportPpapiError(ERROR_PNACL_CREATE_TEMP, pp_error, "Failed to open scratch object file."); - if (use_new_cache_) { - plugin_->nacl_interface()->ReportTranslationFinished( - plugin_->pp_instance(), - PP_FALSE); - } + plugin_->nacl_interface()->ReportTranslationFinished( + plugin_->pp_instance(), + PP_FALSE); return; } // Open the nexe file for connecting ld and sel_ldr. // Start translation when done with this last step of setup! - if (!use_new_cache_) - // In the new cache case, the TempFile has already been created. - temp_nexe_file_.reset(new TempFile(plugin_)); - pp::CompletionCallback cb = callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); temp_nexe_file_->Open(cb, true); diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h index 42f1207..a87b031 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h @@ -15,16 +15,10 @@ #include "native_client/src/shared/srpc/nacl_srpc.h" #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" -#include "ppapi/c/pp_file_info.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" #include "ppapi/cpp/completion_callback.h" -#include "ppapi/cpp/file_io.h" -#include "ppapi/cpp/file_ref.h" -#include "ppapi/cpp/file_system.h" #include "ppapi/native_client/src/trusted/plugin/callback_source.h" #include "ppapi/native_client/src/trusted/plugin/file_downloader.h" -#include "ppapi/native_client/src/trusted/plugin/local_temp_file.h" #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_options.h" @@ -94,7 +88,7 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { // Call this to take ownership of the FD of the translated nexe after // BitcodeToNative has completed (and the finish_callback called). - nacl::DescWrapper* ReleaseTranslatedFD() { return translated_fd_.release(); } + nacl::DescWrapper* ReleaseTranslatedFD(); // Run |translate_notify_callback_| with an error condition that is not // PPAPI specific. Also set ErrorInfo report. @@ -156,10 +150,6 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { // Callbacks for temporary file related stages. // They are invoked from ResourcesDidLoad and proceed in declaration order. - // Invoked when the temporary file system is successfully opened in PPAPI. - void FileSystemDidOpen(int32_t pp_error); - // Invoked after we are sure the PNaCl temporary directory exists. - void DirectoryWasCreated(int32_t pp_error); // Invoke to issue a GET request for bitcode. void OpenBitcodeStream(); // Invoked when we've started an URL fetch for the pexe to check for @@ -168,8 +158,6 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { // Invoked when we've gotten a temp FD for the nexe, either with the nexe // data, or a writeable fd to save to. void NexeFdDidOpen(int32_t pp_error); - // Invoked after we have checked the PNaCl cache for a translated version. - void CachedFileDidOpen(int32_t pp_error); // Invoked when a pexe data chunk arrives (when using streaming translation) void BitcodeStreamGotData(int32_t pp_error, FileStreamData data); // Invoked when a pexe data chunk is compiled. @@ -186,21 +174,6 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { // Invoked when translation is finished. void TranslateFinished(int32_t pp_error); - // If the cache is enabled, open a cache file for write, then copy - // the nexe data from temp_nexe_file_ to> cached_nexe_file_. - // Once the copy is done, we commit it to the cache by renaming the - // cache file to the final name. - void CachedNexeOpenedForWrite(int32_t pp_error); - void DidCopyNexeToCachePartial(int32_t pp_error, int32_t num_read_prev, - int64_t cur_offset); - void NexeWasCopiedToCache(int32_t pp_error); - // If the copy of the nexe to the not-yet-committed-to-cache file - // failed after partial writes, we attempt to delete the partially written - // file. This callback is invoked when the delete is completed. - void CorruptCacheFileWasDeleted(int32_t delete_pp_error, - int32_t orig_pp_error); - // Invoked when the nexe_file_ temporary has been renamed to the nexe name. - void NexeFileWasRenamed(int32_t pp_error); // Invoked when the read descriptor for nexe_file_ is created. void NexeReadDidOpen(int32_t pp_error); @@ -216,20 +189,12 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { pp::CompletionCallbackFactory<PnaclCoordinator, pp::ThreadSafeThreadTraits> callback_factory_; - // Nexe from the final native Link. - nacl::scoped_ptr<nacl::DescWrapper> translated_fd_; - - // Translation creates local temporary files. - nacl::scoped_ptr<pp::FileSystem> file_system_; // The manifest used by resource loading and ld + llc's reverse service // to look up objects and libraries. nacl::scoped_ptr<const Manifest> manifest_; // An auxiliary class that manages downloaded resources (llc and ld nexes). nacl::scoped_ptr<PnaclResources> resources_; - // State used for querying the temporary directory. - nacl::scoped_ptr<pp::FileRef> dir_ref_; - // The URL for the pexe file. nacl::string pexe_url_; // Options for translation. @@ -239,19 +204,9 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { nacl::scoped_ptr<TempFile> obj_file_; // Translated nexe file, produced by the linker. nacl::scoped_ptr<TempFile> temp_nexe_file_; - // Cached nexe file, consumed by sel_ldr. This will be NULL if we do - // not have a writeable cache file. That is currently the case when - // off_the_record_ is true. - nacl::scoped_ptr<LocalTempFile> cached_nexe_file_; - // True if the new cache flow is enabled. Currently set by an environment - // variable on construction. TODO(dschuff): remove old cache stuff. - bool use_new_cache_; // Passed to the browser, which sets it to true if there is a translation // cache hit. PP_Bool is_cache_hit_; - // Passed to the browser, which sets it to the handle for the nexe file - // (either the translated nexe from the cache, or a temp file to write to). - PP_FileHandle nexe_handle_; // Downloader for streaming translation nacl::scoped_ptr<FileDownloader> streaming_downloader_; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_options.cc b/ppapi/native_client/src/trusted/plugin/pnacl_options.cc index 0e684bb..69858831 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_options.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_options.cc @@ -9,21 +9,6 @@ #include "native_client/src/include/nacl_string.h" -namespace { - -nacl::string ReplaceBadFSChars(nacl::string str, - const nacl::string& bad_chars, - const nacl::string& replacement) { - size_t replace_pos = str.find_first_of(bad_chars); - while (replace_pos != nacl::string::npos) { - str = str.replace(replace_pos, 1, replacement); - replace_pos = str.find_first_of(bad_chars); - } - return str; -} - -} // namespace - namespace plugin { PnaclOptions::PnaclOptions() : translate_(false), opt_level_(2) { } @@ -31,25 +16,6 @@ PnaclOptions::PnaclOptions() : translate_(false), opt_level_(2) { } PnaclOptions::~PnaclOptions() { } -nacl::string PnaclOptions::GetCacheKey() const { - // TODO(jvoung): We need to read the PNaCl translator's manifest - // to grab the NaCl / PNaCl ABI version too. - nacl::stringstream ss; - // Cast opt_level_ as int so that it doesn't think it's a char. - ss << "-O:" << static_cast<int>(opt_level_) - << ";cache_validators:" << cache_validators_; - // HTML5 FileSystem-based cache does not allow some characters which - // may appear in URLs, ETags, or Last-Modified times. Once we move to - // our own cache-backend, it will be more tolerant of various cache - // key values. - // See: http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions - nacl::string key = ss.str(); - key = ReplaceBadFSChars(key, "/", "_FWDSLASH_"); - key = ReplaceBadFSChars(key, "\\", "_BCKSLASH_"); - key = ReplaceBadFSChars(key, "\0", "_NULL_"); - return key; -} - void PnaclOptions::set_opt_level(int32_t l) { if (l <= 0) { opt_level_ = 0; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_options.h b/ppapi/native_client/src/trusted/plugin/pnacl_options.h index f998b2c..df2a9aa 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_options.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_options.h @@ -19,16 +19,6 @@ class PnaclOptions { PnaclOptions(); ~PnaclOptions(); - // Return |true| if PNaCl is allowed to cache. - // PNaCl is allowed to cache if the server sends cache validators - // like Last-Modified time or ETags in the HTTP response, and - // it does not send "Cache-Control: no-store". - bool HasCacheKey() const { return (!cache_validators_.empty()); } - - // Return the cache key (which takes into account the bitcode hash, - // as well as the commandline options). - nacl::string GetCacheKey() const; - // Return a character array of \x00 delimited commandline options. std::vector<char> GetOptCommandline() const; @@ -38,17 +28,12 @@ class PnaclOptions { int32_t opt_level() const { return opt_level_; } void set_opt_level(int32_t l); - void set_cache_validators(const nacl::string& c) { - cache_validators_ = c; - } - private: // NOTE: There are users of this class that use the copy constructor. // Currently the default copy constructor is good enough, but // double-check that it is the case when more fields are added. bool translate_; int32_t opt_level_; - nacl::string cache_validators_; }; } // namespace plugin; diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc index fd845a5..2795786 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc @@ -44,10 +44,8 @@ #include "native_client/src/trusted/validator/nacl_file_info.h" #include "ppapi/c/pp_errors.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" #include "ppapi/cpp/core.h" #include "ppapi/cpp/completion_callback.h" -#include "ppapi/cpp/file_io.h" #include "ppapi/native_client/src/trusted/plugin/manifest.h" #include "ppapi/native_client/src/trusted/plugin/plugin.h" @@ -61,8 +59,10 @@ namespace { // For doing crude quota enforcement on writes to temp files. -// We do not allow a temp file bigger than 512 MB for now. -const uint64_t kMaxTempQuota = 0x20000000; +// We do not allow a temp file bigger than 128 MB for now. +// There is currently a limit of 32M for nexe text size, so 128M +// should be plenty for static data +const int64_t kMaxTempQuota = 0x8000000; } // namespace @@ -475,142 +475,36 @@ void PluginReverseInterface::ReportExitStatus(int exit_status) { service_runtime_->set_exit_status(exit_status); } -void PluginReverseInterface::QuotaRequest_MainThreadContinuation( - QuotaRequest* request, - int32_t err) { - if (err != PP_OK) { - return; - } - - switch (request->data.type) { - case plugin::PepperQuotaType: { - const PPB_FileIOTrusted* file_io_trusted = - static_cast<const PPB_FileIOTrusted*>( - pp::Module::Get()->GetBrowserInterface( - PPB_FILEIOTRUSTED_INTERFACE)); - // Copy the request object because this one will be deleted on return. - // copy ctor! - QuotaRequest* cont_for_response = new QuotaRequest(*request); - pp::CompletionCallback quota_cc = WeakRefNewCallback( - anchor_, - this, - &PluginReverseInterface::QuotaRequest_MainThreadResponse, - cont_for_response); - file_io_trusted->WillWrite(request->data.resource, - request->offset, - // TODO(sehr): remove need for cast. - // Unify WillWrite interface vs Quota request. - nacl::assert_cast<int32_t>( - request->bytes_requested), - quota_cc.pp_completion_callback()); - break; - } - case plugin::TempQuotaType: { - uint64_t len = request->offset + request->bytes_requested; - nacl::MutexLocker take(&mu_); - // Do some crude quota enforcement. - if (len > kMaxTempQuota) { - *request->bytes_granted = 0; - } else { - *request->bytes_granted = request->bytes_requested; - } - *request->op_complete_ptr = true; - NaClXCondVarBroadcast(&cv_); - break; - } - } - // request automatically deleted -} - -void PluginReverseInterface::QuotaRequest_MainThreadResponse( - QuotaRequest* request, - int32_t err) { - NaClLog(4, - "PluginReverseInterface::QuotaRequest_MainThreadResponse:" - " (resource=%" NACL_PRIx32 ", offset=%" NACL_PRId64 ", requested=%" - NACL_PRId64 ", err=%" NACL_PRId32 ")\n", - request->data.resource, - request->offset, request->bytes_requested, err); - nacl::MutexLocker take(&mu_); - if (err >= PP_OK) { - *request->bytes_granted = err; - } else { - *request->bytes_granted = 0; - } - *request->op_complete_ptr = true; - NaClXCondVarBroadcast(&cv_); - // request automatically deleted -} - int64_t PluginReverseInterface::RequestQuotaForWrite( nacl::string file_id, int64_t offset, int64_t bytes_to_write) { NaClLog(4, "PluginReverseInterface::RequestQuotaForWrite:" " (file_id='%s', offset=%" NACL_PRId64 ", bytes_to_write=%" NACL_PRId64 ")\n", file_id.c_str(), offset, bytes_to_write); - QuotaData quota_data; - { - nacl::MutexLocker take(&mu_); - uint64_t file_key = STRTOULL(file_id.c_str(), NULL, 10); - if (quota_map_.find(file_key) == quota_map_.end()) { - // Look up failed to find the requested quota managed resource. - NaClLog(4, "PluginReverseInterface::RequestQuotaForWrite: failed...\n"); - return 0; - } - quota_data = quota_map_[file_key]; + uint64_t file_key = STRTOULL(file_id.c_str(), NULL, 10); + nacl::MutexLocker take(&mu_); + if (quota_files_.count(file_key) == 0) { + // Look up failed to find the requested quota managed resource. + NaClLog(4, "PluginReverseInterface::RequestQuotaForWrite: failed...\n"); + return 0; } - // Variables set by requesting quota. - int64_t quota_granted = 0; - bool op_complete = false; - QuotaRequest* continuation = - new QuotaRequest(quota_data, offset, bytes_to_write, "a_granted, - &op_complete); - // The reverse service is running on a background thread and the PPAPI quota - // methods must be invoked only from the main thread. - plugin::WeakRefCallOnMainThread( - anchor_, - 0, /* delay in ms */ - this, - &plugin::PluginReverseInterface::QuotaRequest_MainThreadContinuation, - continuation); - // Wait for the main thread to request quota and signal completion. - // It is also possible that the main thread will signal shut down. - bool shutting_down; - do { - nacl::MutexLocker take(&mu_); - for (;;) { - shutting_down = shutting_down_; - if (op_complete || shutting_down) { - break; - } - NaClXCondVarWait(&cv_, &mu_); - } - } while (0); - if (shutting_down) return 0; - return quota_granted; -} -void PluginReverseInterface::AddQuotaManagedFile(const nacl::string& file_id, - const pp::FileIO& file_io) { - PP_Resource resource = file_io.pp_resource(); - NaClLog(4, - "PluginReverseInterface::AddQuotaManagedFile: " - "(file_id='%s', file_io_ref=%" NACL_PRIx32 ")\n", - file_id.c_str(), resource); - nacl::MutexLocker take(&mu_); - uint64_t file_key = STRTOULL(file_id.c_str(), NULL, 10); - QuotaData data(plugin::PepperQuotaType, resource); - quota_map_[file_key] = data; + // Because we now only support this interface for tempfiles which are not + // pepper objects, we can just do some crude quota enforcement here rather + // than calling out to pepper from the main thread. + if (offset + bytes_to_write >= kMaxTempQuota) + return 0; + + return bytes_to_write; } void PluginReverseInterface::AddTempQuotaManagedFile( const nacl::string& file_id) { NaClLog(4, "PluginReverseInterface::AddTempQuotaManagedFile: " "(file_id='%s')\n", file_id.c_str()); - nacl::MutexLocker take(&mu_); uint64_t file_key = STRTOULL(file_id.c_str(), NULL, 10); - QuotaData data(plugin::TempQuotaType, 0); - quota_map_[file_key] = data; + nacl::MutexLocker take(&mu_); + quota_files_.insert(file_key); } ServiceRuntime::ServiceRuntime(Plugin* plugin, diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.h b/ppapi/native_client/src/trusted/plugin/service_runtime.h index e7ebbbc..4241737 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.h +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.h @@ -11,7 +11,7 @@ #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_ #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_SERVICE_RUNTIME_H_ -#include <map> +#include <set> #include "native_client/src/include/nacl_macros.h" #include "native_client/src/include/nacl_scoped_ptr.h" @@ -123,35 +123,20 @@ struct CloseManifestEntryResource { bool* op_result_ptr; }; -enum QuotaDataType { - PepperQuotaType, - TempQuotaType -}; - -struct QuotaData { - QuotaData(QuotaDataType type_, PP_Resource resource_) - : type(type_), resource(resource_) {} - QuotaData() - : type(PepperQuotaType), resource(0) {} - - QuotaDataType type; - PP_Resource resource; -}; - struct QuotaRequest { public: - QuotaRequest(QuotaData quota_data, + QuotaRequest(PP_Resource pp_resource, int64_t start_offset, int64_t quota_bytes_requested, int64_t* quota_bytes_granted, bool* op_complete) - : data(quota_data), + : resource(pp_resource), offset(start_offset), bytes_requested(quota_bytes_requested), bytes_granted(quota_bytes_granted), op_complete_ptr(op_complete) { } - QuotaData data; + PP_Resource resource; int64_t offset; int64_t bytes_requested; int64_t* bytes_granted; @@ -225,14 +210,6 @@ class PluginReverseInterface: public nacl::ReverseInterface { CloseManifestEntryResource* cls, int32_t err); - virtual void QuotaRequest_MainThreadContinuation( - QuotaRequest* request, - int32_t err); - - virtual void QuotaRequest_MainThreadResponse( - QuotaRequest* request, - int32_t err); - private: nacl::WeakRefAnchor* anchor_; // holds a ref Plugin* plugin_; // value may be copied, but should be used only in @@ -241,7 +218,7 @@ class PluginReverseInterface: public nacl::ReverseInterface { ServiceRuntime* service_runtime_; NaClMutex mu_; NaClCondVar cv_; - std::map<int64_t, QuotaData> quota_map_; + std::set<int64_t> quota_files_; bool shutting_down_; nacl::scoped_ptr<PnaclCoordinator> pnacl_coordinator_; diff --git a/ppapi/native_client/src/trusted/plugin/temporary_file.cc b/ppapi/native_client/src/trusted/plugin/temporary_file.cc index 46167a1..2bb65bf 100644 --- a/ppapi/native_client/src/trusted/plugin/temporary_file.cc +++ b/ppapi/native_client/src/trusted/plugin/temporary_file.cc @@ -37,14 +37,6 @@ TempFile::~TempFile() { PLUGIN_PRINTF(("TempFile::~TempFile\n")); } -bool TempFile::SetExistingFd(PP_FileHandle handle) { - // Check if we got a bad handle or if Open has already been called. - if (handle == PP_kInvalidFileHandle || read_wrapper_.get() != NULL) - return false; - existing_handle_ = handle; - return true; -} - void TempFile::Open(const pp::CompletionCallback& cb, bool writeable) { PLUGIN_PRINTF(("TempFile::Open\n")); PP_FileHandle file_handle; diff --git a/ppapi/native_client/src/trusted/plugin/temporary_file.h b/ppapi/native_client/src/trusted/plugin/temporary_file.h index 966945c..09a4250 100644 --- a/ppapi/native_client/src/trusted/plugin/temporary_file.h +++ b/ppapi/native_client/src/trusted/plugin/temporary_file.h @@ -41,9 +41,6 @@ class TempFile { explicit TempFile(Plugin* plugin); ~TempFile(); - // Set an existing Fd instead of getting one from the nacl interface on open. - // Must be called before Open. - bool SetExistingFd(PP_FileHandle handle); // Opens a temporary file object and descriptor wrapper referring to the file. // If |writeable| is true, the descriptor will be opened for writing, and // write_wrapper will return a valid pointer, otherwise it will return NULL. @@ -59,6 +56,8 @@ class TempFile { return read_wrapper_.release(); } + PP_FileHandle* existing_handle() { return &existing_handle_; } + // For quota management. const nacl::string identifier() const { return nacl::string(reinterpret_cast<const char*>(identifier_)); |