summaryrefslogtreecommitdiffstats
path: root/ppapi/native_client
diff options
context:
space:
mode:
authorjvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-06 15:32:47 +0000
committerjvoung@google.com <jvoung@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-06 15:32:47 +0000
commit979b48da6e16cd33d2132aae2dd7c1c426a6a95c (patch)
tree3e0450fde33bac023afb20f5ab2a983b99d75f5f /ppapi/native_client
parent81e513a94e5ab4e1108aae7b06f754115f219051 (diff)
downloadchromium_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')
-rw-r--r--ppapi/native_client/src/trusted/plugin/local_temp_file.h2
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc238
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h75
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc9
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h5
-rw-r--r--ppapi/native_client/src/trusted/plugin/temporary_file.cc23
-rw-r--r--ppapi/native_client/src/trusted/plugin/temporary_file.h10
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