diff options
author | jvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-06 15:32:47 +0000 |
---|---|---|
committer | jvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-06 15:32:47 +0000 |
commit | 979b48da6e16cd33d2132aae2dd7c1c426a6a95c (patch) | |
tree | 3e0450fde33bac023afb20f5ab2a983b99d75f5f /ppapi/native_client | |
parent | 81e513a94e5ab4e1108aae7b06f754115f219051 (diff) | |
download | chromium_src-979b48da6e16cd33d2132aae2dd7c1c426a6a95c.zip chromium_src-979b48da6e16cd33d2132aae2dd7c1c426a6a95c.tar.gz chromium_src-979b48da6e16cd33d2132aae2dd7c1c426a6a95c.tar.bz2 |
Retry "Add an interface for PNaCl to check if the session is incognito..."
(previously 149749).
Again, we use the interface to use the cache when available, or to
load from a temporary file in incognito, when the cache is not available.
Differences from previous try:
* double-fd-close bug.
* compiler warnings that show up in scons build.
BUG= http://code.google.com/p/nativeclient/issues/detail?id=2683
Review URL: https://chromiumcodereview.appspot.com/10834173
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150093 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/native_client')
7 files changed, 246 insertions, 116 deletions
diff --git a/ppapi/native_client/src/trusted/plugin/local_temp_file.h b/ppapi/native_client/src/trusted/plugin/local_temp_file.h index 3e3858d..51d2095 100644 --- a/ppapi/native_client/src/trusted/plugin/local_temp_file.h +++ b/ppapi/native_client/src/trusted/plugin/local_temp_file.h @@ -82,7 +82,7 @@ class LocalTempFile { const nacl::string identifier() const { return nacl::string(reinterpret_cast<const char*>(identifier_)); } - const pp::FileIO& write_file_io() const { return *write_io_; } + pp::FileIO* write_file_io() const { return write_io_.get(); } private: NACL_DISALLOW_COPY_AND_ASSIGN(LocalTempFile); diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index 790e021..3377b6a 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -7,6 +7,7 @@ #include <utility> #include <vector> +#include "native_client/src/include/checked_cast.h" #include "native_client/src/include/portability_io.h" #include "native_client/src/shared/platform/nacl_check.h" #include "native_client/src/trusted/plugin/local_temp_file.h" @@ -16,14 +17,15 @@ #include "native_client/src/trusted/plugin/pnacl_translate_thread.h" #include "native_client/src/trusted/plugin/service_runtime.h" #include "native_client/src/trusted/plugin/temporary_file.h" -#include "native_client/src/trusted/service_runtime/include/sys/stat.h" +#include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppb_file_io.h" #include "ppapi/cpp/file_io.h" namespace { const char kPnaclTempDir[] = "/.pnacl"; +const uint32_t kCopyBufSize = 512 << 10; } namespace plugin { @@ -182,8 +184,13 @@ PnaclCoordinator* PnaclCoordinator::BitcodeToNative( PnaclCoordinator* coordinator = new PnaclCoordinator(plugin, pexe_url, cache_identity, translate_notify_callback); - PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p)\n", - reinterpret_cast<const void*>(coordinator->manifest_.get()))); + coordinator->off_the_record_ = + plugin->nacl_interface()->IsOffTheRecord(); + PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p, " + "off_the_record=%b)\n", + reinterpret_cast<const void*>(coordinator->manifest_.get()), + coordinator->off_the_record_)); + // Load llc and ld. std::vector<nacl::string> resource_urls; resource_urls.push_back(PnaclUrls::GetLlcUrl()); @@ -234,7 +241,8 @@ PnaclCoordinator::PnaclCoordinator( manifest_(new ExtensionManifest(plugin->url_util())), pexe_url_(pexe_url), cache_identity_(cache_identity), - error_already_reported_(false) { + error_already_reported_(false), + off_the_record_(false) { PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", static_cast<void*>(this), static_cast<void*>(plugin))); callback_factory_.Initialize(this); @@ -294,51 +302,140 @@ void PnaclCoordinator::ReportPpapiError(int32_t pp_error) { void PnaclCoordinator::TranslateFinished(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished (pp_error=%" NACL_PRId32")\n", pp_error)); - // Save the translate error code, and inspect after cleaning up junk files. - // Note: If there was a surfaway and the file objects were actually - // destroyed, then we are in trouble since the obj_file_, nexe_file_, - // etc. may have been destroyed. - // TODO(jvoung,sehr): Fix. - // If there was an error already set (e.g. pexe load failure) then we want - // to use the first one, (which might be something useful) rather than - // the one from the compiler, (which is always just PP_ERROR_FAILED) - if (translate_finish_error_ == PP_OK) translate_finish_error_ = pp_error; - - // Close the nexe temporary file. - if (nexe_file_ != NULL) { - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasClosed); - nexe_file_->Close(cb); + // Bail out if there was an earlier error (e.g., pexe load failure). + if (translate_finish_error_ != PP_OK) { + ReportPpapiError(translate_finish_error_); + return; + } + // Bail out if there is an error from the translation thread. + if (pp_error != PP_OK) { + ReportPpapiError(pp_error); + return; + } + + // 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 (cache_identity_ != "" && 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::NexeFileWasClosed(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasClosed (pp_error=%" - NACL_PRId32")\n", pp_error)); +void PnaclCoordinator::CachedNexeOpenedForWrite(int32_t pp_error) { if (pp_error != PP_OK) { - ReportPpapiError(pp_error); + ReportPpapiError(pp_error, "Failed to open cache file for write."); return; } - // Now that cleanup of the obj file is done, check the old TranslateFinished - // error code to see if we should proceed normally or not. - if (translate_finish_error_ != PP_OK) { - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasDeleted); - nexe_file_->Delete(cb); + + // 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); +} - // Rename the nexe file to the cache id. - 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::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) { + // TODO(jvoung): This should probably try to delete the cache file + // before returning... + ReportPpapiError(pp_error, "Failed to copy nexe to cache."); + 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(cache_identity_, cb); } void PnaclCoordinator::NexeFileWasRenamed(int32_t pp_error) { @@ -350,11 +447,12 @@ void PnaclCoordinator::NexeFileWasRenamed(int32_t pp_error) { ReportPpapiError(pp_error, "Failed to place cached bitcode translation."); return; } - nexe_file_->FinishRename(); - // Open the nexe temporary file for reading. + + cached_nexe_file_->FinishRename(); + // Open the cache file for reading. pp::CompletionCallback cb = callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); - nexe_file_->OpenRead(cb); + cached_nexe_file_->OpenRead(cb); } void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { @@ -364,18 +462,17 @@ void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { ReportPpapiError(pp_error, "Failed to open translated nexe."); return; } - // Transfer ownership of the nexe wrapper to the coordinator. - translated_fd_.reset(nexe_file_->release_read_wrapper()); + + // 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()); + } plugin_->EnqueueProgressEvent(Plugin::kProgressEventProgress); translate_notify_callback_.Run(pp_error); } -void PnaclCoordinator::NexeFileWasDeleted(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasDeleted (pp_error=%" - NACL_PRId32")\n", pp_error)); - ReportPpapiError(translate_finish_error_); -} - void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::ResourcesDidLoad (pp_error=%" NACL_PRId32")\n", pp_error)); @@ -383,12 +480,17 @@ void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { ReportPpapiError(pp_error, "resources failed to load."); return; } - // Open the local temporary file system to create the temporary files - // for the object and nexe. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::FileSystemDidOpen); - if (!file_system_->Open(0, cb)) { - ReportNonPpapiError("failed to open file system."); + + if (!off_the_record_) { + // Open the local temporary FS to see if we get a hit in the cache. + pp::CompletionCallback cb = + callback_factory_.NewCallback(&PnaclCoordinator::FileSystemDidOpen); + if (!file_system_->Open(0, cb)) { + ReportNonPpapiError("failed to open file system."); + } + } else { + // We don't have a cache, so do the non-cached codepath. + CachedFileDidOpen(PP_ERROR_FAILED); } } @@ -399,8 +501,7 @@ void PnaclCoordinator::FileSystemDidOpen(int32_t pp_error) { ReportPpapiError(pp_error, "file system didn't open."); return; } - dir_ref_.reset(new pp::FileRef(*file_system_, - kPnaclTempDir)); + dir_ref_.reset(new pp::FileRef(*file_system_, kPnaclTempDir)); // Attempt to create the directory. pp::CompletionCallback cb = callback_factory_.NewCallback(&PnaclCoordinator::DirectoryWasCreated); @@ -416,12 +517,12 @@ void PnaclCoordinator::DirectoryWasCreated(int32_t pp_error) { return; } if (cache_identity_ != "") { - nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), - nacl::string(kPnaclTempDir), - cache_identity_)); + cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), + nacl::string(kPnaclTempDir), + cache_identity_)); pp::CompletionCallback cb = callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen); - nexe_file_->OpenRead(cb); + cached_nexe_file_->OpenRead(cb); } else { // For now, tolerate lack of cache identity... CachedFileDidOpen(PP_ERROR_FAILED); @@ -467,9 +568,9 @@ void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%" NACL_PRId32")\n", pp_error)); if (pp_error != PP_OK) { - // Defer reporting the error and obj_file/nexe_file cleanup until after - // the translation thread returns, because it may be accessing the - // coordinator's objects or writing to the files. + // Defer reporting the error and cleanup until after the translation + // thread returns, because it may be accessing the coordinator's + // objects or writing to the files. translate_finish_error_ = pp_error; error_info_.SetReport(ERROR_UNKNOWN, nacl::string("PnaclCoordinator: pexe load failed.")); @@ -499,11 +600,10 @@ void PnaclCoordinator::ObjectFileDidOpen(int32_t pp_error) { } // Create the nexe file for connecting ld and sel_ldr. // Start translation when done with this last step of setup! - nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), - nacl::string(kPnaclTempDir))); + temp_nexe_file_.reset(new TempFile(plugin_)); pp::CompletionCallback cb = callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); - nexe_file_->OpenWrite(cb); + temp_nexe_file_->Open(cb); } void PnaclCoordinator::RunTranslate(int32_t pp_error) { @@ -519,7 +619,7 @@ void PnaclCoordinator::RunTranslate(int32_t pp_error) { manifest_.get(), ld_manifest_.get(), obj_file_.get(), - nexe_file_.get(), + temp_nexe_file_.get(), &error_info_, resources_.get(), plugin_); diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h index 3b3b828..944240e 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h @@ -62,17 +62,18 @@ class TempFile; // The coordinator proceeds through several states. They are // LOAD_TRANSLATOR_BINARIES // Complete when ResourcesDidLoad is invoked. -// OPEN_LOCAL_FILE_SYSTEM -// 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 -// Complete when ObjectReadDidOpen is invoked. +// +// If cache is enabled: +// OPEN_LOCAL_FILE_SYSTEM +// 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_FOR_LLC_TO_LD_COMMUNICATION +// Complete when ObjectFileDidOpen is invoked. // OPEN_TMP_FOR_LD_WRITING // Complete when NexeWriteDidOpen is invoked. // PREPARE_PEXE_FOR_STREAMING @@ -81,16 +82,17 @@ class TempFile; // Complete when RunTranslate returns. // TRANSLATION_COMPLETE // Complete when TranslateFinished is invoked. -// CLOSE_OBJECT_FILE -// Complete when ObjectFileWasClosed is invoked. -// DELETE_OBJECT_FILE -// Complete when ObjectFileWasDeleted is invoked. -// CLOSE_NEXE_FILE -// Complete when NexeFileWasClosed is invoked. -// RENAME_NEXE_FILE +// +// If cache is enabled: +// OPEN_CACHE_FOR_WRITE +// Complete when CachedNexeOpenedForWrite is invoked +// COPY_NEXE_TO_CACHE +// Complete when NexeWasCopiedToCache is invoked. +// RENAME_CACHE_FILE // Complete when NexeFileWasRenamed is invoked. +// // OPEN_NEXE_FOR_SEL_LDR -// Complete when NexeReadDidOpen is invoked. +// Complete when NexeReadDidOpen is invoked. class PnaclCoordinator: public CallbackSource<FileStreamData> { public: virtual ~PnaclCoordinator(); @@ -155,21 +157,27 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { void BitcodeStreamDidFinish(int32_t pp_error); // Invoked when the write descriptor for obj_file_ is created. void ObjectFileDidOpen(int32_t pp_error); - // Invoked when the descriptors for nexe_file_ have been closed. - void NexeFileWasClosed(int32_t 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); - // Invoked if there was an error and we've cleaned up the nexe_file_ temp. - void NexeFileWasDeleted(int32_t pp_error); - // Once llc and ld nexes have been loaded and the two temporary files have // been created, this starts the translation. Translation starts two // subprocesses, one for llc and one for ld. void RunTranslate(int32_t pp_error); + // 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); + // 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); + // Keeps track of the pp_error upon entry to TranslateFinished, // for inspection after cleanup. int32_t translate_finish_error_; @@ -209,8 +217,12 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { nacl::string cache_identity_; // Object file, produced by the translator and consumed by the linker. nacl::scoped_ptr<TempFile> obj_file_; - // Translated nexe file, produced by the linker and consumed by sel_ldr. - nacl::scoped_ptr<LocalTempFile> nexe_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_; // Downloader for streaming translation nacl::scoped_ptr<FileDownloader> streaming_downloader_; @@ -221,6 +233,9 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { // was already run/consumed. bool error_already_reported_; + // True if compilation is off_the_record. + bool off_the_record_; + // The helper thread used to do translations via SRPC. // Keep this last in declaration order to ensure the other variables // haven't been destroyed yet when its destructor runs. diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc index b1b93e8..6704ff5 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc @@ -33,7 +33,7 @@ void PnaclTranslateThread::RunTranslate( const Manifest* manifest, const Manifest* ld_manifest, TempFile* obj_file, - LocalTempFile* nexe_file, + TempFile* nexe_file, ErrorInfo* error_info, PnaclResources* resources, Plugin* plugin) { @@ -123,7 +123,7 @@ void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) { void PnaclTranslateThread::DoTranslate() { ErrorInfo error_info; SrpcParams params; - nacl::DescWrapper* llc_out_file = obj_file_->get_wrapper(); + nacl::DescWrapper* llc_out_file = obj_file_->write_wrapper(); { nacl::MutexLocker ml(&subprocess_mu_); @@ -233,7 +233,7 @@ bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library, TranslateFailed("Link process could not reset object file"); return false; } - nacl::DescWrapper* ld_in_file = obj_file_->get_wrapper(); + nacl::DescWrapper* ld_in_file = obj_file_->read_wrapper(); nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper(); { @@ -249,8 +249,7 @@ bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library, ld_subprocess_active_ = true; PluginReverseInterface* ld_reverse = ld_subprocess_->service_runtime()->rev_interface(); - ld_reverse->AddQuotaManagedFile(nexe_file_->identifier(), - nexe_file_->write_file_io()); + ld_reverse->AddTempQuotaManagedFile(nexe_file_->identifier()); } // Run LD. if (!ld_subprocess_->InvokeSrpcMethod("RunWithDefaultCommandLine", diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h index 8ebb216..727e4f6 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h @@ -25,7 +25,6 @@ class DescWrapper; namespace plugin { -class LocalTempFile; class Manifest; class NaClSubprocess; class Plugin; @@ -43,7 +42,7 @@ class PnaclTranslateThread { const Manifest* manifest, const Manifest* ld_manifest, TempFile* obj_file, - LocalTempFile* nexe_file, + TempFile* nexe_file, ErrorInfo* error_info, PnaclResources* resources, Plugin* plugin); @@ -108,7 +107,7 @@ class PnaclTranslateThread { const Manifest* manifest_; const Manifest* ld_manifest_; TempFile* obj_file_; - LocalTempFile* nexe_file_; + TempFile* nexe_file_; ErrorInfo* coordinator_error_info_; PnaclResources* resources_; Plugin* plugin_; diff --git a/ppapi/native_client/src/trusted/plugin/temporary_file.cc b/ppapi/native_client/src/trusted/plugin/temporary_file.cc index 4cdd04d..fe8b779 100644 --- a/ppapi/native_client/src/trusted/plugin/temporary_file.cc +++ b/ppapi/native_client/src/trusted/plugin/temporary_file.cc @@ -69,16 +69,31 @@ void TempFile::Open(const pp::CompletionCallback& cb) { return; } + // dup the fd to make allow making a non-Quota-based wrapper. + // sel_ldr currently does not allow loading from Quota-backed descs, + // only plain host descs. It's probably good hygiene to separate the + // read wrapper from the write wrapper anyway. + int32_t read_fd = DUP(fd); + if (read_fd == NACL_NO_FILE_DESC) { + PLUGIN_PRINTF(("TempFile::Open DUP failed\n")); + core->CallOnMainThread(0, cb, PP_ERROR_FAILED); + return; + } + // The descriptor for a writeable file needs to have quota management. - wrapper_.reset( - plugin_->wrapper_factory()->MakeFileDescQuota(fd, O_RDWR, identifier_)); + write_wrapper_.reset( + plugin_->wrapper_factory()->MakeFileDescQuota(fd, O_RDWR, identifier_)); + read_wrapper_.reset( + plugin_->wrapper_factory()->MakeFileDesc(read_fd, O_RDONLY)); core->CallOnMainThread(0, cb, PP_OK); } bool TempFile::Reset() { PLUGIN_PRINTF(("TempFile::Reset\n")); - CHECK(wrapper_.get() != NULL); - nacl_off64_t newpos = wrapper_->Seek(0, SEEK_SET); + // Use the write_wrapper_ to reset the file pos. The read_wrapper_ is also + // backed by the same file, so it should also reset. + CHECK(write_wrapper_.get() != NULL); + nacl_off64_t newpos = write_wrapper_->Seek(0, SEEK_SET); return newpos >= 0; } diff --git a/ppapi/native_client/src/trusted/plugin/temporary_file.h b/ppapi/native_client/src/trusted/plugin/temporary_file.h index 298656d..0fe6d26 100644 --- a/ppapi/native_client/src/trusted/plugin/temporary_file.h +++ b/ppapi/native_client/src/trusted/plugin/temporary_file.h @@ -47,9 +47,10 @@ class TempFile { // Accessors. // The nacl::DescWrapper* for the writeable version of the file. - nacl::DescWrapper* get_wrapper() { return wrapper_.get(); } - nacl::DescWrapper* release_wrapper() { - return wrapper_.release(); + nacl::DescWrapper* write_wrapper() { return write_wrapper_.get(); } + nacl::DescWrapper* read_wrapper() { return read_wrapper_.get(); } + nacl::DescWrapper* release_read_wrapper() { + return read_wrapper_.release(); } // For quota management. @@ -61,7 +62,8 @@ class TempFile { NACL_DISALLOW_COPY_AND_ASSIGN(TempFile); Plugin* plugin_; - nacl::scoped_ptr<nacl::DescWrapper> wrapper_; + nacl::scoped_ptr<nacl::DescWrapper> read_wrapper_; + nacl::scoped_ptr<nacl::DescWrapper> write_wrapper_; // An identifier string used for quota request processing. The quota // interface needs a string that is unique per sel_ldr instance only, so |