diff options
author | karen@chromium.org <karen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-31 18:58:00 +0000 |
---|---|---|
committer | karen@chromium.org <karen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-31 18:58:00 +0000 |
commit | e4741c02737b4f2b9ddb8f94d8b39fa6ed64831a (patch) | |
tree | 03b0aabe0d40cfbd75e0d95c150094e2ed94cbdc /ppapi | |
parent | cb72d19ff1887449c70979650b0bf4170358c502 (diff) | |
download | chromium_src-e4741c02737b4f2b9ddb8f94d8b39fa6ed64831a.zip chromium_src-e4741c02737b4f2b9ddb8f94d8b39fa6ed64831a.tar.gz chromium_src-e4741c02737b4f2b9ddb8f94d8b39fa6ed64831a.tar.bz2 |
Revert 119758 - Add skeleton for file cleanup and cache renaming during translation.
Plumbing the cache name through remains to be done, as does correctly handling
quota for object temporary file removal.
BUG=none
TEST=none
Review URL: https://chromiumcodereview.appspot.com/9288046
TBR=sehr@google.com
Review URL: https://chromiumcodereview.appspot.com/9312002
git-svn-id: svn://svn.chromium.org/chrome/branches/1025/src@119929 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
10 files changed, 342 insertions, 479 deletions
diff --git a/ppapi/native_client/src/trusted/plugin/build.scons b/ppapi/native_client/src/trusted/plugin/build.scons index ea885fe..0052a46 100644 --- a/ppapi/native_client/src/trusted/plugin/build.scons +++ b/ppapi/native_client/src/trusted/plugin/build.scons @@ -68,6 +68,7 @@ common_inputs = [ 'plugin.cc', 'pnacl_coordinator.cc', 'pnacl_resources.cc', + 'pnacl_srpc_lib.cc', 'scriptable_handle.cc', 'service_runtime.cc', 'srpc_client.cc', diff --git a/ppapi/native_client/src/trusted/plugin/nacl_subprocess.cc b/ppapi/native_client/src/trusted/plugin/nacl_subprocess.cc index 646c411..567eb3c 100644 --- a/ppapi/native_client/src/trusted/plugin/nacl_subprocess.cc +++ b/ppapi/native_client/src/trusted/plugin/nacl_subprocess.cc @@ -4,10 +4,6 @@ #include "native_client/src/trusted/plugin/nacl_subprocess.h" -#include <stdarg.h> - -#include "native_client/src/trusted/plugin/browser_interface.h" -#include "native_client/src/trusted/plugin/method_map.h" #include "native_client/src/trusted/plugin/plugin_error.h" #include "native_client/src/trusted/plugin/scriptable_handle.h" #include "native_client/src/trusted/plugin/service_runtime.h" @@ -15,7 +11,13 @@ namespace plugin { nacl::string NaClSubprocess::description() const { - return description_; + nacl::stringstream ss; + if (assigned_id_ == kMainSubprocessId) { + ss << "main subprocess"; + } else { + ss << "helper subprocess #" << assigned_id_; + } + return ss.str(); } nacl::string NaClSubprocess::detailed_description() const { @@ -71,84 +73,4 @@ bool NaClSubprocess::Invoke(uintptr_t method_id, SrpcParams* params) const { return srpc_client_->Invoke(method_id, params); } -bool NaClSubprocess::InvokeSrpcMethod(const nacl::string& method_name, - const nacl::string& input_signature, - SrpcParams* params, - ...) { - va_list vl; - va_start(vl, params); - bool result = VInvokeSrpcMethod(method_name, input_signature, params, vl); - va_end(vl); - return result; -} - -bool NaClSubprocess::VInvokeSrpcMethod(const nacl::string& method_name, - const nacl::string& input_signature, - SrpcParams* params, - va_list vl) { - uintptr_t method_ident; - if (!SetupSrpcInvocation(method_name, params, &method_ident)) { - return false; - } - - // Set up inputs. - for (size_t i = 0; i < input_signature.length(); ++i) { - char c = input_signature[i]; - // Only handle the limited number of SRPC types used for PNaCl. - // Add more as needed. - switch (c) { - default: - PLUGIN_PRINTF(("PnaclSrpcLib::InvokeSrpcMethod unhandled type: %c\n", - c)); - return false; - case NACL_SRPC_ARG_TYPE_BOOL: { - int input = va_arg(vl, int); - params->ins()[i]->u.bval = input; - break; - } - case NACL_SRPC_ARG_TYPE_DOUBLE: { - double input = va_arg(vl, double); - params->ins()[i]->u.dval = input; - break; - } - case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: { - // SrpcParam's destructor *should* free the dup'ed string. - const char* orig_str = va_arg(vl, const char*); - char* input = strdup(orig_str); - params->ins()[i]->arrays.str = input; - break; - } - case NACL_SRPC_ARG_TYPE_HANDLE: { - NaClSrpcImcDescType input = va_arg(vl, NaClSrpcImcDescType); - params->ins()[i]->u.hval = input; - break; - } - case NACL_SRPC_ARG_TYPE_INT: { - int32_t input = va_arg(vl, int32_t); - params->ins()[i]->u.ival = input; - break; - } - case NACL_SRPC_ARG_TYPE_LONG: { - int64_t input = va_arg(vl, int64_t); - params->ins()[i]->u.lval = input; - break; - } - } - } - - return Invoke(method_ident, params); -} - -bool NaClSubprocess::SetupSrpcInvocation(const nacl::string& method_name, - SrpcParams* params, - uintptr_t* method_ident) { - *method_ident = browser_interface_->StringToIdentifier(method_name); - if (!HasMethod(*method_ident)) { - PLUGIN_PRINTF(("SetupSrpcInvocation (no %s method found)\n", - method_name.c_str())); - return false; - } - return InitParams(*method_ident, params); -} - } // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/nacl_subprocess.h b/ppapi/native_client/src/trusted/plugin/nacl_subprocess.h index 035b4d4..32ae0ed 100644 --- a/ppapi/native_client/src/trusted/plugin/nacl_subprocess.h +++ b/ppapi/native_client/src/trusted/plugin/nacl_subprocess.h @@ -11,32 +11,27 @@ #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NACL_SUBPROCESS_H_ #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_NACL_SUBPROCESS_H_ -#include <stdarg.h> - -#include "native_client/src/include/nacl_macros.h" #include "native_client/src/include/nacl_string.h" -#include "native_client/src/include/portability.h" - #include "native_client/src/trusted/plugin/service_runtime.h" #include "native_client/src/trusted/plugin/srpc_client.h" namespace plugin { -class BrowserInterface; class Plugin; class ServiceRuntime; -class SrpcParams; +// Identifier for helper NaCl nexes. Should be non-negative for valid nexes. +typedef int32_t NaClSubprocessId; +const NaClSubprocessId kInvalidNaClSubprocessId = -1; +const NaClSubprocessId kMainSubprocessId = -2; // A class representing an instance of a NaCl module, loaded by the plugin. class NaClSubprocess { public: - NaClSubprocess(const nacl::string& description, - BrowserInterface* browser_interface, + NaClSubprocess(NaClSubprocessId assigned_id, ServiceRuntime* service_runtime, SrpcClient* srpc_client) - : description_(description), - browser_interface_(browser_interface), + : assigned_id_(assigned_id), service_runtime_(service_runtime), srpc_client_(srpc_client) { } @@ -67,36 +62,17 @@ class NaClSubprocess { bool InitParams(uintptr_t method_id, SrpcParams* params) const; bool Invoke(uintptr_t method_id, SrpcParams* params) const; - // Invoke an Srpc Method. |out_params| must be allocated and cleaned up - // outside of this function, but it will be initialized by this function, and - // on success any out-params (if any) will be placed in |out_params|. - // Input types must be listed in |input_signature|, with the actual - // arguments passed in as var-args. Returns |true| on success. - bool InvokeSrpcMethod(const nacl::string& method_name, - const nacl::string& input_signature, - SrpcParams* out_params, - ...); - // Fully shut down the subprocess. void Shutdown(); private: NACL_DISALLOW_COPY_AND_ASSIGN(NaClSubprocess); - bool SetupSrpcInvocation(const nacl::string& method_name, - SrpcParams* params, - uintptr_t* kMethodIdent); + NaClSubprocessId assigned_id_; - bool VInvokeSrpcMethod(const nacl::string& method_name, - const nacl::string& signature, - SrpcParams* params, - va_list vl); - - nacl::string description_; - - BrowserInterface* browser_interface_; // The service runtime representing the NaCl module instance. nacl::scoped_ptr<ServiceRuntime> service_runtime_; + // Ownership of srpc_client taken from the service runtime. nacl::scoped_ptr<SrpcClient> srpc_client_; }; diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc index 8274663..6f1949d 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.cc +++ b/ppapi/native_client/src/trusted/plugin/plugin.cc @@ -633,9 +633,15 @@ void Plugin::ShutDownSubprocesses() { PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", main_subprocess_.detailed_description().c_str())); - // Shut down service runtime. This must be done before all other calls so + // Shutdown service runtime. This must be done before all other calls so // they don't block forever when waiting for the upcall thread to exit. main_subprocess_.Shutdown(); + for (size_t i = 0; i < nacl_subprocesses_.size(); ++i) { + PLUGIN_PRINTF(("Plugin::ShutDownSubprocesses (%s)\n", + nacl_subprocesses_[i]->detailed_description().c_str())); + delete nacl_subprocesses_[i]; + } + nacl_subprocesses_.clear(); PLUGIN_PRINTF(("Plugin::ShutDownSubprocess (this=%p, return)\n", static_cast<void*>(this))); @@ -726,8 +732,8 @@ bool Plugin::LoadNaClModule(nacl::DescWrapper* wrapper, // associated listener threads do not go unjoined because if they // outlive the Plugin object, they will not be memory safe. ShutDownSubprocesses(); - if (!LoadNaClModuleCommon(wrapper, &main_subprocess_, manifest_.get(), - true, error_info, init_done_cb, crash_cb)) { + if (!(LoadNaClModuleCommon(wrapper, &main_subprocess_, manifest_.get(), + true, error_info, init_done_cb, crash_cb))) { return false; } PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n", @@ -745,15 +751,16 @@ bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) { return true; } -NaClSubprocess* Plugin::LoadHelperNaClModule(nacl::DescWrapper* wrapper, - const Manifest* manifest, - ErrorInfo* error_info) { +NaClSubprocessId Plugin::LoadHelperNaClModule(nacl::DescWrapper* wrapper, + const Manifest* manifest, + ErrorInfo* error_info) { + NaClSubprocessId next_id = next_nacl_subprocess_id(); nacl::scoped_ptr<NaClSubprocess> nacl_subprocess( - new NaClSubprocess("helper module", browser_interface_, NULL, NULL)); + new(std::nothrow) NaClSubprocess(next_id, NULL, NULL)); if (NULL == nacl_subprocess.get()) { error_info->SetReport(ERROR_SEL_LDR_INIT, "unable to allocate helper subprocess."); - return NULL; + return kInvalidNaClSubprocessId; } // Do not report UMA stats for translator-related nexes. @@ -775,13 +782,14 @@ NaClSubprocess* Plugin::LoadHelperNaClModule(nacl::DescWrapper* wrapper, // manifest is a per-plugin-instance object, not a per // NaClSubprocess object. && StartSrpcServicesCommon(nacl_subprocess.get(), error_info))) { - return NULL; + return kInvalidNaClSubprocessId; } PLUGIN_PRINTF(("Plugin::LoadHelperNaClModule (%s)\n", nacl_subprocess.get()->detailed_description().c_str())); - return nacl_subprocess.release(); + nacl_subprocesses_.push_back(nacl_subprocess.release()); + return next_id; } char* Plugin::LookupArgument(const char* key) { @@ -990,7 +998,7 @@ Plugin::Plugin(PP_Instance pp_instance) argc_(-1), argn_(NULL), argv_(NULL), - main_subprocess_("main subprocess", NULL, NULL, NULL), + main_subprocess_(kMainSubprocessId, NULL, NULL), nacl_ready_state_(UNSENT), nexe_error_reported_(false), wrapper_factory_(NULL), @@ -1033,7 +1041,7 @@ Plugin::~Plugin() { ScriptableHandle* scriptable_handle_ = scriptable_handle(); ScriptableHandle::Unref(&scriptable_handle_); - // ShutDownSubprocesses shuts down the main subprocess, which shuts + // ShutDownSubprocesses shuts down the subprocesses, which shuts // down the main ServiceRuntime object, which kills the subprocess. // As a side effect of the subprocess being killed, the reverse // services thread(s) will get EOF on the reverse channel(s), and diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gypi b/ppapi/native_client/src/trusted/plugin/plugin.gypi index d2fee95..a6947ac 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.gypi +++ b/ppapi/native_client/src/trusted/plugin/plugin.gypi @@ -17,6 +17,7 @@ 'plugin.cc', 'pnacl_coordinator.cc', 'pnacl_resources.cc', + 'pnacl_srpc_lib.cc', 'scriptable_handle.cc', 'service_runtime.cc', 'srpc_client.cc', diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h index 6f5f374..014f175 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.h +++ b/ppapi/native_client/src/trusted/plugin/plugin.h @@ -148,10 +148,10 @@ class Plugin : public pp::InstancePrivate { // A helper SRPC NaCl module can be loaded given a DescWrapper. // Blocks until the helper module signals initialization is done. // Does not update nacl_module_origin(). - // Returns NULL or the NaClSubprocess of the new helper NaCl module. - NaClSubprocess* LoadHelperNaClModule(nacl::DescWrapper* wrapper, - const Manifest* manifest, - ErrorInfo* error_info); + // Returns kInvalidNaClSubprocessId or the ID of the new helper NaCl module. + NaClSubprocessId LoadHelperNaClModule(nacl::DescWrapper* wrapper, + const Manifest* manifest, + ErrorInfo* error_info); // Returns the argument value for the specified key, or NULL if not found. // The callee retains ownership of the result. @@ -245,6 +245,17 @@ class Plugin : public pp::InstancePrivate { nexe_error_reported_ = val; } + // Get the NaCl module subprocess that was assigned the ID |id|. + NaClSubprocess* nacl_subprocess(NaClSubprocessId id) const { + if (kInvalidNaClSubprocessId == id) { + return NULL; + } + return nacl_subprocesses_[id]; + } + NaClSubprocessId next_nacl_subprocess_id() const { + return static_cast<NaClSubprocessId>(nacl_subprocesses_.size()); + } + nacl::DescWrapperFactory* wrapper_factory() const { return wrapper_factory_; } // Requests a NaCl manifest download from a |url| relative to the page origin. @@ -348,7 +359,7 @@ class Plugin : public pp::InstancePrivate { char* argv[]); void LoadMethods(); // Shuts down socket connection, service runtime, and receive thread, - // in this order, for the main nacl subprocess. + // in this order, for all spun up NaCl module subprocesses. void ShutDownSubprocesses(); ScriptableHandle* scriptable_handle() const { return scriptable_handle_; } @@ -466,8 +477,9 @@ class Plugin : public pp::InstancePrivate { char** argn_; char** argv_; - // Keep track of the NaCl module subprocess that was spun up in the plugin. + // Keep track of the NaCl module subprocesses that were spun up in the plugin. NaClSubprocess main_subprocess_; + std::vector<NaClSubprocess*> nacl_subprocesses_; nacl::string plugin_base_url_; nacl::string manifest_base_url_; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index 57d2f11..ecea98b 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -17,8 +17,8 @@ #include "native_client/src/trusted/plugin/nexe_arch.h" #include "native_client/src/trusted/plugin/plugin.h" #include "native_client/src/trusted/plugin/plugin_error.h" +#include "native_client/src/trusted/plugin/pnacl_srpc_lib.h" #include "native_client/src/trusted/plugin/utility.h" -#include "native_client/src/trusted/service_runtime/include/sys/stat.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppb_file_io.h" @@ -32,7 +32,6 @@ namespace { const char kLlcUrl[] = "llc"; const char kLdUrl[] = "ld"; -const char kPnaclTempDir[] = "/.pnacl"; nacl::string ExtensionUrl() { // TODO(sehr,jvoung): Find a better way to express the URL for the pnacl @@ -64,18 +63,19 @@ nacl::string Random32CharHexString(struct NaClDescRng* rng) { // Some constants for PnaclFileDescPair::GetFD readability. const bool kReadOnly = false; const bool kWriteable = true; + } // namespace ////////////////////////////////////////////////////////////////////// -// Local temporary file access. +// Temporary file descriptors. ////////////////////////////////////////////////////////////////////// -LocalTempFile::LocalTempFile(Plugin* plugin, - pp::FileSystem* file_system, - PnaclCoordinator* coordinator) +PnaclFileDescPair::PnaclFileDescPair(Plugin* plugin, + pp::FileSystem* file_system, + PnaclCoordinator* coordinator) : plugin_(plugin), file_system_(file_system), coordinator_(coordinator) { - PLUGIN_PRINTF(("LocalTempFile::LocalTempFile (plugin=%p, " + PLUGIN_PRINTF(("PnaclFileDescPair::PnaclFileDescPair (plugin=%p, " "file_system=%p, coordinator=%p)\n", static_cast<void*>(plugin), static_cast<void*>(file_system), static_cast<void*>(coordinator))); @@ -85,42 +85,39 @@ LocalTempFile::LocalTempFile(Plugin* plugin, CHECK(NaClDescRngCtor(rng_desc_)); file_io_trusted_ = static_cast<const PPB_FileIOTrusted*>( pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE)); + // Get a random temp file name. + filename_ = "/" + Random32CharHexString(rng_desc_); } -LocalTempFile::~LocalTempFile() { - PLUGIN_PRINTF(("LocalTempFile::~LocalTempFile\n")); +PnaclFileDescPair::~PnaclFileDescPair() { + PLUGIN_PRINTF(("PnaclFileDescPair::~PnaclFileDescPair\n")); NaClDescUnref(reinterpret_cast<NaClDesc*>(rng_desc_)); } -void LocalTempFile::OpenWrite(const pp::CompletionCallback& cb) { - PLUGIN_PRINTF(("LocalTempFile::OpenWrite\n")); +void PnaclFileDescPair::Open(const pp::CompletionCallback& cb) { + PLUGIN_PRINTF(("PnaclFileDescPair::Open\n")); done_callback_ = cb; - // If we don't already have a filename, generate one. - if (filename_ == "") { - // Get a random temp file name. - filename_ = - nacl::string(kPnaclTempDir) + "/" + Random32CharHexString(rng_desc_); - // Remember the ref used to open for writing and reading. - file_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str())); - } - // Open the writeable file. + + write_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str())); write_io_.reset(new pp::FileIO(plugin_)); + read_ref_.reset(new pp::FileRef(*file_system_, filename_.c_str())); + read_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, + callback_factory_.NewCallback(&PnaclFileDescPair::WriteFileDidOpen); + // Open the writeable file. + write_io_->Open(*write_ref_, + PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE, 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 +int32_t PnaclFileDescPair::GetFD(int32_t pp_error, + const pp::Resource& resource, + bool is_writable) { + PLUGIN_PRINTF(("PnaclFileDescPair::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")); + PLUGIN_PRINTF(("PnaclFileDescPair::GetFD pp_error != PP_OK\n")); return -1; } int32_t file_desc = @@ -132,27 +129,22 @@ int32_t LocalTempFile::GetFD(int32_t pp_error, 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")); + PLUGIN_PRINTF(("PnaclFileDescPair::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")); + PLUGIN_PRINTF(("PnaclFileDescPair::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=%" +void PnaclFileDescPair::WriteFileDidOpen(int32_t pp_error) { + PLUGIN_PRINTF(("PnaclFileDescPair::WriteFileDidOpen (pp_error=%" NACL_PRId32")\n", pp_error)); - if (pp_error == PP_ERROR_FILEEXISTS) { - // Filenames clashed, retry. - filename_ = ""; - OpenWrite(done_callback_); - } // Remember the object temporary file descriptor. int32_t fd = GetFD(pp_error, *write_io_, kWriteable); if (fd < 0) { @@ -160,23 +152,14 @@ void LocalTempFile::WriteFileDidOpen(int32_t pp_error) { return; } write_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDWR)); - // Run the client's completion callback. - pp::Core* core = pp::Module::Get()->core(); - core->CallOnMainThread(0, done_callback_, PP_OK); -} - -void LocalTempFile::OpenRead(const pp::CompletionCallback& cb) { - PLUGIN_PRINTF(("LocalTempFile::OpenRead\n")); - 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); + callback_factory_.NewCallback(&PnaclFileDescPair::ReadFileDidOpen); + // Open the read only file. + read_io_->Open(*read_ref_, PP_FILEOPENFLAG_READ, open_read_cb); } -void LocalTempFile::ReadFileDidOpen(int32_t pp_error) { - PLUGIN_PRINTF(("LocalTempFile::ReadFileDidOpen (pp_error=%" +void PnaclFileDescPair::ReadFileDidOpen(int32_t pp_error) { + PLUGIN_PRINTF(("PnaclFileDescPair::ReadFileDidOpen (pp_error=%" NACL_PRId32")\n", pp_error)); // Remember the object temporary file descriptor. int32_t fd = GetFD(pp_error, *read_io_, kReadOnly); @@ -190,39 +173,6 @@ void LocalTempFile::ReadFileDidOpen(int32_t pp_error) { core->CallOnMainThread(0, done_callback_, PP_OK); } -void LocalTempFile::Close(const pp::CompletionCallback& cb) { - PLUGIN_PRINTF(("LocalTempFile::Close\n")); - // 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\n")); - file_ref_->Delete(cb); -} - -void LocalTempFile::Rename(const nacl::string& new_name, - const pp::CompletionCallback& cb) { - PLUGIN_PRINTF(("LocalTempFile::Rename\n")); - // Rename the temporary file. - filename_ = new_name; - nacl::scoped_ptr<pp::FileRef> old_ref(file_ref_.release()); - file_ref_.reset(new pp::FileRef(*file_system_, new_name.c_str())); - old_ref->Rename(*file_ref_, cb); -} - ////////////////////////////////////////////////////////////////////// // Pnacl-specific manifest support. ////////////////////////////////////////////////////////////////////// @@ -437,13 +387,11 @@ PnaclCoordinator::PnaclCoordinator( PnaclCoordinator::~PnaclCoordinator() { PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p)\n", static_cast<void*>(this))); - // Stopping the translate thread will cause the translate thread to try to - // run translation_complete_callback_ on the main thread. This destructor is - // running from the main thread, and by the time it exits, callback_factory_ - // will have been destroyed. This will result in the cancellation of - // translation_complete_callback_, so no notification will be delivered. + // Join helper thread which will block the page from refreshing while a + // translation is happening. if (translate_thread_.get() != NULL) { SetSubprocessesShouldDie(true); + NaClThreadJoin(translate_thread_.get()); } NaClMutexDtor(&subprocess_mu_); } @@ -488,79 +436,10 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) { NACL_PRId32")\n", pp_error)); if (pp_error != PP_OK) { ReportPpapiError(pp_error); - // TODO(sehr): Delete the object and nexe temporary files. - return; - } - // Close the object temporary file. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::ObjectFileWasClosed); - obj_file_->Close(cb); -} - -void PnaclCoordinator::ObjectFileWasClosed(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::ObjectFileWasClosed (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error != PP_OK) { - ReportPpapiError(pp_error); - return; - } - // Delete the object temporary file. - // TODO(sehr): delete the temporary file once the quota updates work. - // pp::CompletionCallback cb = - // callback_factory_.NewCallback(&PnaclCoordinator::ObjectFileWasDeleted); - // obj_file_->Delete(cb); - ObjectFileWasDeleted(PP_OK); -} - -void PnaclCoordinator::ObjectFileWasDeleted(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::ObjectFileWasDeleted (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error != PP_OK) { - ReportPpapiError(pp_error); - return; - } - // Close the nexe temporary file. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasClosed); - nexe_file_->Close(cb); -} - -void PnaclCoordinator::NexeFileWasClosed(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasClosed (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error != PP_OK) { - ReportPpapiError(pp_error); - return; - } - // TODO(sehr): enable renaming once cache ids are available. - // Rename the nexe file to the cache id. - // pp::CompletionCallback cb = - // callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); - // nexe_file_->Rename(new_name, cb); - NexeFileWasRenamed(PP_OK); -} - -void PnaclCoordinator::NexeFileWasRenamed(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::NexeFileWasRenamed (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error != PP_OK) { - ReportPpapiError(pp_error); - return; - } - // Open the nexe temporary file for reading. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); - nexe_file_->OpenRead(cb); -} - -void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::NexeReadDidOpen (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error != PP_OK) { - ReportPpapiError(pp_error); return; } // Transfer ownership of the nexe wrapper to the coordinator. + // TODO(sehr): figure out when/how to delete/reap these temporary files. translated_fd_.reset(nexe_file_->release_read_wrapper()); plugin_->EnqueueProgressEvent(Plugin::kProgressEventProgress); translate_notify_callback_.Run(pp_error); @@ -572,7 +451,8 @@ void PnaclCoordinator::TranslateFailed(const nacl::string& error_string) { pp::Core* core = pp::Module::Get()->core(); error_info_.SetReport(ERROR_UNKNOWN, nacl::string("PnaclCoordinator: ") + error_string); - core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED); + core->CallOnMainThread(0, translate_done_cb_, PP_ERROR_FAILED); + NaClThreadExit(1); } void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { @@ -598,95 +478,29 @@ 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_io_.reset(new pp::FileIO(plugin_)); - // Attempt to open the directory. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::DirectoryWasOpened); - dir_io_->Open(*dir_ref_, PP_FILEOPENFLAG_READ, cb); -} - -void PnaclCoordinator::DirectoryWasOpened(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::DirectoryWasOpened (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error == PP_ERROR_FILENOTFOUND) { - // Pathname did not exist, create it. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::DirectoryWasCreated); - dir_ref_->MakeDirectory(cb); - return; - } - if (pp_error != PP_OK) { - ReportPpapiError(pp_error, "directory couldn't be opened."); - return; - } - // Query for information on the directory. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::DirectoryWasQueried); - dir_io_->Query(&dir_info_, cb); -} - -void PnaclCoordinator::DirectoryWasQueried(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::DirectoryWasQueried (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error != PP_OK) { - ReportPpapiError(pp_error, "directory query failed."); - return; - } - dir_io_->Close(); - dir_io_.reset(NULL); - // Ensure directory has the right properties. - if (dir_info_.type != PP_FILETYPE_DIRECTORY || - dir_info_.system_type != PP_FILESYSTEMTYPE_LOCALTEMPORARY) { - ReportPpapiError(pp_error, "bad temporary directory."); - return; - } - // A valid directory existed, use it. - DirectoryWasCreated(PP_OK); -} - -void PnaclCoordinator::DirectoryWasCreated(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::DirectoryWasCreated (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error != PP_OK) { - ReportPpapiError(pp_error, "directory creation failed."); - return; - } // Create the object file pair for connecting llc and ld. - obj_file_.reset(new LocalTempFile(plugin_, file_system_.get(), this)); - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::ObjectWriteDidOpen); - obj_file_->OpenWrite(cb); -} - -void PnaclCoordinator::ObjectWriteDidOpen(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::ObjectWriteDidOpen (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error != PP_OK) { - ReportPpapiError(pp_error); - return; - } + obj_file_.reset(new PnaclFileDescPair(plugin_, file_system_.get(), this)); pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::ObjectReadDidOpen); - obj_file_->OpenRead(cb); + callback_factory_.NewCallback(&PnaclCoordinator::ObjectPairDidOpen); + obj_file_->Open(cb); } -void PnaclCoordinator::ObjectReadDidOpen(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::ObjectReadDidOpen (pp_error=%" +void PnaclCoordinator::ObjectPairDidOpen(int32_t pp_error) { + PLUGIN_PRINTF(("PnaclCoordinator::ObjectPairDidOpen (pp_error=%" NACL_PRId32")\n", pp_error)); if (pp_error != PP_OK) { ReportPpapiError(pp_error); return; } - // Create the nexe file for connecting ld and sel_ldr. - nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), this)); + // Create the nexe file pair for connecting ld and sel_ldr. + nexe_file_.reset(new PnaclFileDescPair(plugin_, file_system_.get(), this)); pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::NexeWriteDidOpen); - nexe_file_->OpenWrite(cb); + callback_factory_.NewCallback(&PnaclCoordinator::NexePairDidOpen); + nexe_file_->Open(cb); } -void PnaclCoordinator::NexeWriteDidOpen(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::NexeWriteDidOpen (pp_error=%" +void PnaclCoordinator::NexePairDidOpen(int32_t pp_error) { + PLUGIN_PRINTF(("PnaclCoordinator::NexePairDidOpen (pp_error=%" NACL_PRId32")\n", pp_error)); if (pp_error != PP_OK) { ReportPpapiError(pp_error); @@ -712,7 +526,7 @@ void PnaclCoordinator::RunTranslate(int32_t pp_error) { pexe_wrapper_.reset(plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); // Invoke llc followed by ld off the main thread. This allows use of // blocking RPCs that would otherwise block the JavaScript main thread. - report_translate_finished_ = + translate_done_cb_ = callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); translate_thread_.reset(new NaClThread); if (translate_thread_ == NULL) { @@ -734,14 +548,14 @@ NaClSubprocess* PnaclCoordinator::StartSubprocess( PLUGIN_PRINTF(("PnaclCoordinator::StartSubprocess (url_for_nexe=%s)\n", url_for_nexe.c_str())); nacl::DescWrapper* wrapper = resources_->WrapperForUrl(url_for_nexe); - nacl::scoped_ptr<NaClSubprocess> subprocess( - plugin_->LoadHelperNaClModule(wrapper, manifest, &error_info_)); - if (subprocess.get() == NULL) { + NaClSubprocessId id = + plugin_->LoadHelperNaClModule(wrapper, manifest, &error_info_); + if (kInvalidNaClSubprocessId == id) { PLUGIN_PRINTF(( - "PnaclCoordinator::StartSubprocess: subprocess creation failed\n")); + "PnaclCoordinator::StartSubprocess: invalid subprocess id\n")); return NULL; } - return subprocess.release(); + return plugin_->nacl_subprocess(id); } // TODO(sehr): the thread body should be in a class by itself with a delegate @@ -755,18 +569,18 @@ void WINAPI PnaclCoordinator::DoTranslateThread(void* arg) { coordinator->StartSubprocess(kLlcUrl, coordinator->manifest_.get())); if (llc_subprocess == NULL) { coordinator->TranslateFailed("Compile process could not be created."); - return; } // Run LLC. SrpcParams params; nacl::DescWrapper* llc_out_file = coordinator->obj_file_->write_wrapper(); - if (!llc_subprocess->InvokeSrpcMethod("RunWithDefaultCommandLine", - "hh", - ¶ms, - coordinator->pexe_wrapper_->desc(), - llc_out_file->desc())) { + if (!PnaclSrpcLib::InvokeSrpcMethod(browser_interface, + llc_subprocess.get(), + "RunWithDefaultCommandLine", + "hh", + ¶ms, + coordinator->pexe_wrapper_->desc(), + llc_out_file->desc())) { coordinator->TranslateFailed("compile failed."); - return; } // LLC returns values that are used to determine how linking is done. int is_shared_library = (params.outs()[0]->u.ival != 0); @@ -777,39 +591,42 @@ void WINAPI PnaclCoordinator::DoTranslateThread(void* arg) { arg, is_shared_library, soname.c_str(), lib_dependencies.c_str())); // Shut down the llc subprocess. - llc_subprocess.reset(NULL); + llc_subprocess.release(); if (coordinator->SubprocessesShouldDie()) { - coordinator->TranslateFailed("stopped by coordinator."); - return; + PLUGIN_PRINTF(( + "PnaclCoordinator::DoTranslateThread: killed by coordinator.\n")); + NaClThreadExit(1); } nacl::scoped_ptr<NaClSubprocess> ld_subprocess( coordinator->StartSubprocess(kLdUrl, coordinator->ld_manifest_.get())); if (ld_subprocess == NULL) { coordinator->TranslateFailed("Link process could not be created."); - return; } nacl::DescWrapper* ld_in_file = coordinator->obj_file_->read_wrapper(); nacl::DescWrapper* ld_out_file = coordinator->nexe_file_->write_wrapper(); - if (!ld_subprocess->InvokeSrpcMethod("RunWithDefaultCommandLine", - "hhiCC", - ¶ms, - ld_in_file->desc(), - ld_out_file->desc(), - is_shared_library, - soname.c_str(), - lib_dependencies.c_str())) { + if (!PnaclSrpcLib::InvokeSrpcMethod(browser_interface, + ld_subprocess.get(), + "RunWithDefaultCommandLine", + "hhiCC", + ¶ms, + ld_in_file->desc(), + ld_out_file->desc(), + is_shared_library, + soname.c_str(), + lib_dependencies.c_str())) { coordinator->TranslateFailed("link failed."); - return; } PLUGIN_PRINTF(("PnaclCoordinator: link (coordinator=%p) succeeded\n", arg)); // Shut down the ld subprocess. - ld_subprocess.reset(NULL); + ld_subprocess.release(); if (coordinator->SubprocessesShouldDie()) { - coordinator->TranslateFailed("stopped by coordinator."); - return; + PLUGIN_PRINTF(( + "PnaclCoordinator::DoTranslateThread: killed by coordinator.\n")); + NaClThreadExit(1); } pp::Core* core = pp::Module::Get()->core(); - core->CallOnMainThread(0, coordinator->report_translate_finished_, PP_OK); + core->CallOnMainThread(0, coordinator->translate_done_cb_, PP_OK); + NaClThreadExit(0); } bool PnaclCoordinator::SubprocessesShouldDie() { diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h index 304bdd7..77eedda 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h @@ -50,29 +50,20 @@ class PnaclCoordinator; // read by: sel_ldr (passed in explicitly to command channel) // -// LocalTempFile represents a file used as a temporary between stages in +// PnaclFileDescPair 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 { +class PnaclFileDescPair { public: - LocalTempFile(Plugin* plugin, - pp::FileSystem* file_system, - PnaclCoordinator* coordinator); - ~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); - + PnaclFileDescPair(Plugin* plugin, + pp::FileSystem* file_system, + PnaclCoordinator* coordinator); + ~PnaclFileDescPair(); + // Opens a pair of file IO objects referring to a randomly named file in + // file_system_. One IO is for writing the file and another for reading it. + void Open(const pp::CompletionCallback& cb); // Accessors. // The nacl::DescWrapper* for the writeable version of the file. nacl::DescWrapper* write_wrapper() { return write_wrapper_.get(); } @@ -86,7 +77,7 @@ class LocalTempFile { } private: - NACL_DISALLOW_COPY_AND_ASSIGN(LocalTempFile); + NACL_DISALLOW_COPY_AND_ASSIGN(PnaclFileDescPair); // Gets the POSIX file descriptor for a resource. int32_t GetFD(int32_t pp_error, @@ -96,20 +87,19 @@ class LocalTempFile { 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_; PnaclCoordinator* coordinator_; const PPB_FileIOTrusted* file_io_trusted_; - pp::CompletionCallbackFactory<LocalTempFile> callback_factory_; + pp::CompletionCallbackFactory<PnaclFileDescPair> callback_factory_; nacl::string filename_; - nacl::scoped_ptr<pp::FileRef> file_ref_; // The PPAPI and wrapper state for the writeable file. + nacl::scoped_ptr<pp::FileRef> write_ref_; 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::FileRef> read_ref_; 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. @@ -162,34 +152,21 @@ class PnaclRefCount { // Complete when ResourcesDidLoad is invoked. // OPEN_LOCAL_FILE_SYSTEM // Complete when FileSystemDidOpen is invoked. -// OPENED_PNACL_TEMP_DIRECTORY -// Complete when DirectoryWasOpened is invoked. -// QUERIED_PNACL_TEMP_DIRECTORY -// Complete when DirectoryWasQueried is invoked. -// CREATED_PNACL_TEMP_DIRECTORY -// Complete when DirectoryWasCreated is invoked. -// 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. -// OPEN_TMP_FOR_LD_WRITING -// Complete when NexeWriteDidOpen is invoked. +// OPEN_TMP_FOP_LLC_TO_LD_COMMUNICATION +// Complete when ObjectPairDidOpen is invoked. +// OPEN_TMP_FOR_LD_TO_SEL_LDR_COMMUNICATION +// Complete when NexePairDidOpen is invoked. // PREPARE_PEXE_FOR_STREAMING // Complete when RunTranslate is invoked. // START_LD_AND_LLC_SUBPROCESS_AND_INITIATE_TRANSLATION // 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 -// Complete when NexeFileWasRenamed is invoked. -// OPEN_NEXE_FOR_SEL_LDR -// Complete when NexeReadDidOpen is invoked. +// +// It should be noted that at the moment we are not properly freeing the +// PPAPI resources used for the temporary files used in translation. Until +// that is fixed, (4) and (5) should be done in that order. +// TODO(sehr): Fix freeing of temporary files. class PnaclCoordinator { public: virtual ~PnaclCoordinator(); @@ -236,28 +213,10 @@ class PnaclCoordinator { // 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 the PNaCl temporary directory was opened for querying. - void DirectoryWasOpened(int32_t pp_error); - // Invoked after the PNaCl temporary directory was queried. - void DirectoryWasQueried(int32_t pp_error); - // Invoked after we are sure the PNaCl temporary directory exists. - void DirectoryWasCreated(int32_t pp_error); - // Invoked when the write descriptor for obj_file_ is created. - void ObjectWriteDidOpen(int32_t pp_error); - // Invoked when the read descriptor for obj_file_ is created. - void ObjectReadDidOpen(int32_t pp_error); - // Invoked when the read descriptor for nexe_file_ is created. - void NexeWriteDidOpen(int32_t pp_error); - // Invoked when the descriptors for obj_file_ have been closed. - void ObjectFileWasClosed(int32_t pp_error); - // Invoked when the obj_file_ temporary has been deleted. - void ObjectFileWasDeleted(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 when the obj_file_ temporary file I/O pair is created. + void ObjectPairDidOpen(int32_t pp_error); + // Invoked when the nexe_file_ temporary file I/O pair is created. + void NexePairDidOpen(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 @@ -312,21 +271,16 @@ class PnaclCoordinator { // 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_; - nacl::scoped_ptr<pp::FileIO> dir_io_; - PP_FileInfo dir_info_; - // The URL for the pexe file. nacl::string pexe_url_; // Borrowed reference which must outlive the thread. nacl::scoped_ptr<nacl::DescWrapper> pexe_wrapper_; // Object file, produced by the translator and consumed by the linker. - nacl::scoped_ptr<LocalTempFile> obj_file_; + nacl::scoped_ptr<PnaclFileDescPair> obj_file_; // Translated nexe file, produced by the linker and consumed by sel_ldr. - nacl::scoped_ptr<LocalTempFile> nexe_file_; + nacl::scoped_ptr<PnaclFileDescPair> nexe_file_; // Callbacks to run when tasks or completed or an error has occurred. - pp::CompletionCallback report_translate_finished_; + pp::CompletionCallback translate_done_cb_; // Used to report information when errors (PPAPI or otherwise) are reported. ErrorInfo error_info_; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.cc b/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.cc new file mode 100644 index 0000000..7fd33b5 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.cc @@ -0,0 +1,111 @@ +// Copyright (c) 2011 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 "native_client/src/trusted/plugin/pnacl_srpc_lib.h" + +#include <stdarg.h> + +#include "native_client/src/trusted/plugin/browser_interface.h" +#include "native_client/src/trusted/plugin/method_map.h" +#include "native_client/src/trusted/plugin/nacl_subprocess.h" + +namespace plugin { + +bool PnaclSrpcLib::InvokeSrpcMethod(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + const nacl::string& input_signature, + SrpcParams* params, + ...) { + va_list vl; + va_start(vl, params); + bool result = VInvokeSrpcMethod(browser_interface, + subprocess, + method_name, + input_signature, + params, + vl); + va_end(vl); + return result; +} + +bool PnaclSrpcLib::VInvokeSrpcMethod(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + const nacl::string& input_signature, + SrpcParams* params, + va_list vl) { + uintptr_t kMethodIdent; + if (!SetupSrpcInvocation(browser_interface, + subprocess, + method_name, + params, + &kMethodIdent)) { + return false; + } + + // Set up inputs. + for (size_t i = 0; i < input_signature.length(); ++i) { + char c = input_signature[i]; + // Only handle the limited number of SRPC types used for PNaCl. + // Add more as needed. + switch (c) { + default: + PLUGIN_PRINTF(("PnaclSrpcLib::InvokeSrpcMethod unhandled type: %c\n", + c)); + return false; + case NACL_SRPC_ARG_TYPE_BOOL: { + int input = va_arg(vl, int); + params->ins()[i]->u.bval = input; + break; + } + case NACL_SRPC_ARG_TYPE_DOUBLE: { + double input = va_arg(vl, double); + params->ins()[i]->u.dval = input; + break; + } + case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: { + // SrpcParam's destructor *should* free the dup'ed string. + const char* orig_str = va_arg(vl, const char*); + char* input = strdup(orig_str); + params->ins()[i]->arrays.str = input; + break; + } + case NACL_SRPC_ARG_TYPE_HANDLE: { + NaClSrpcImcDescType input = va_arg(vl, NaClSrpcImcDescType); + params->ins()[i]->u.hval = input; + break; + } + case NACL_SRPC_ARG_TYPE_INT: { + int32_t input = va_arg(vl, int32_t); + params->ins()[i]->u.ival = input; + break; + } + case NACL_SRPC_ARG_TYPE_LONG: { + int64_t input = va_arg(vl, int64_t); + params->ins()[i]->u.lval = input; + break; + } + } + } + + return subprocess->Invoke(kMethodIdent, params); +} + + +bool PnaclSrpcLib::SetupSrpcInvocation(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + SrpcParams* params, + uintptr_t* kMethodIdent) { + *kMethodIdent = browser_interface->StringToIdentifier(method_name); + if (!(subprocess->HasMethod(*kMethodIdent))) { + PLUGIN_PRINTF(("SetupSrpcInvocation (no %s method found)\n", + method_name.c_str())); + return false; + } + return subprocess->InitParams(*kMethodIdent, params); +} + +} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.h b/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.h new file mode 100644 index 0000000..847b468 --- /dev/null +++ b/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.h @@ -0,0 +1,61 @@ +// Copyright (c) 2011 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_PNACL_SRPC_LIB_H_ +#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_SRPC_LIB_H_ + +// Routines to simplify SRPC invocations. + +#include <stdarg.h> +#include "native_client/src/include/nacl_macros.h" +#include "native_client/src/include/nacl_string.h" +#include "native_client/src/include/portability.h" + +namespace plugin { + +class BrowserInterface; +class NaClSubprocess; +class SrpcParams; + +// TODO(jvoung): See if anything can be shared between this and +// src/shared/srpc/invoke.c + +// This is just a namespace to collect methods for setting up and invoking +// SPRC methods against a NaClSubprocess. +class PnaclSrpcLib { + public: + // Invoke an Srpc Method on the NaCl subprocess |subprocess|. + // |out_params| must be allocated and cleaned up outside of this function, + // but it will be initialized by this function, and on success + // any out-params (if any) will be placed in |out_params|. + // Input types must be listed in |input_signature|, with the actual + // arguments passed in as var-args. + // Returns |true| on success. + static bool InvokeSrpcMethod(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + const nacl::string& input_signature, + SrpcParams* out_params, + ...); + + private: + NACL_DISALLOW_COPY_AND_ASSIGN(PnaclSrpcLib); + + static bool SetupSrpcInvocation(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + SrpcParams* params, + uintptr_t* kMethodIdent); + + static bool VInvokeSrpcMethod(BrowserInterface* browser_interface, + const NaClSubprocess* subprocess, + const nacl::string& method_name, + const nacl::string& signature, + SrpcParams* params, + va_list vl); +}; + +} // namespace plugin; + +#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_SRPC_LIB_H_ |