| Index: ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
|
| 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 441345aada0a7a0777efd9f5a69f0209c9ee5cdc..b1b93e82ebbd2ed87447bbd0bce48a8762980fdd 100644
|
| --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
|
| +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
|
| @@ -13,8 +13,8 @@
|
|
|
| namespace plugin {
|
|
|
| -PnaclTranslateThread::PnaclTranslateThread() : subprocesses_should_die_(false),
|
| - current_rev_interface_(NULL),
|
| +PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false),
|
| + ld_subprocess_active_(false),
|
| done_(false),
|
| manifest_(NULL),
|
| ld_manifest_(NULL),
|
| @@ -122,28 +122,37 @@ void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) {
|
|
|
| void PnaclTranslateThread::DoTranslate() {
|
| ErrorInfo error_info;
|
| - nacl::scoped_ptr<NaClSubprocess> llc_subprocess(
|
| - StartSubprocess(PnaclUrls::GetLlcUrl(), manifest_, &error_info));
|
| - if (llc_subprocess == NULL) {
|
| - TranslateFailed("Compile process could not be created: " +
|
| - error_info.message());
|
| - return;
|
| - }
|
| - // Run LLC.
|
| SrpcParams params;
|
| nacl::DescWrapper* llc_out_file = obj_file_->get_wrapper();
|
| - PluginReverseInterface* llc_reverse =
|
| - llc_subprocess->service_runtime()->rev_interface();
|
| - llc_reverse->AddTempQuotaManagedFile(obj_file_->identifier());
|
| - RegisterReverseInterface(llc_reverse);
|
|
|
| - if (!llc_subprocess->InvokeSrpcMethod("StreamInit",
|
| - "h",
|
| - ¶ms,
|
| - llc_out_file->desc())) {
|
| - // StreamInit returns an error message if the RPC fails.
|
| - TranslateFailed(nacl::string("Stream init failed: ") +
|
| - nacl::string(params.outs()[0]->arrays.str));
|
| + {
|
| + nacl::MutexLocker ml(&subprocess_mu_);
|
| + llc_subprocess_.reset(
|
| + StartSubprocess(PnaclUrls::GetLlcUrl(), manifest_, &error_info));
|
| + if (llc_subprocess_ == NULL) {
|
| + TranslateFailed("Compile process could not be created: " +
|
| + error_info.message());
|
| + return;
|
| + }
|
| + llc_subprocess_active_ = true;
|
| + // Run LLC.
|
| + PluginReverseInterface* llc_reverse =
|
| + llc_subprocess_->service_runtime()->rev_interface();
|
| + llc_reverse->AddTempQuotaManagedFile(obj_file_->identifier());
|
| + }
|
| +
|
| + if (!llc_subprocess_->InvokeSrpcMethod("StreamInit",
|
| + "h",
|
| + ¶ms,
|
| + llc_out_file->desc())) {
|
| + if (llc_subprocess_->srpc_client()->GetLastError() ==
|
| + NACL_SRPC_RESULT_APP_ERROR) {
|
| + // The error message is only present if the error was returned from llc
|
| + TranslateFailed(nacl::string("Stream init failed: ") +
|
| + nacl::string(params.outs()[0]->arrays.str));
|
| + } else {
|
| + TranslateFailed("Stream init internal error");
|
| + }
|
| return;
|
| }
|
|
|
| @@ -163,11 +172,11 @@ void PnaclTranslateThread::DoTranslate() {
|
| data_buffers_.pop_front();
|
| NaClXMutexUnlock(&cond_mu_);
|
| PLUGIN_PRINTF(("StreamChunk\n"));
|
| - if (!llc_subprocess->InvokeSrpcMethod("StreamChunk",
|
| - "C",
|
| - ¶ms,
|
| - &data[0],
|
| - data.size())) {
|
| + if (!llc_subprocess_->InvokeSrpcMethod("StreamChunk",
|
| + "C",
|
| + ¶ms,
|
| + &data[0],
|
| + data.size())) {
|
| TranslateFailed("Compile stream chunk failed.");
|
| return;
|
| }
|
| @@ -175,18 +184,20 @@ void PnaclTranslateThread::DoTranslate() {
|
| } else {
|
| NaClXMutexUnlock(&cond_mu_);
|
| }
|
| - if (SubprocessesShouldDie()) {
|
| - TranslateFailed("Stopped by coordinator.");
|
| - return;
|
| - }
|
| }
|
| PLUGIN_PRINTF(("PnaclTranslateThread done with chunks\n"));
|
| // Finish llc.
|
| - if(!llc_subprocess->InvokeSrpcMethod("StreamEnd",
|
| + if(!llc_subprocess_->InvokeSrpcMethod("StreamEnd",
|
| "",
|
| ¶ms)) {
|
| PLUGIN_PRINTF(("PnaclTranslateThread StreamEnd failed\n"));
|
| - TranslateFailed(params.outs()[3]->arrays.str);
|
| + if (llc_subprocess_->srpc_client()->GetLastError() ==
|
| + NACL_SRPC_RESULT_APP_ERROR) {
|
| + // The error string is only present if the error was sent back from llc
|
| + TranslateFailed(params.outs()[3]->arrays.str);
|
| + } else {
|
| + TranslateFailed("Compile StreamEnd internal error");
|
| + }
|
| return;
|
| }
|
| // LLC returns values that are used to determine how linking is done.
|
| @@ -199,12 +210,10 @@ void PnaclTranslateThread::DoTranslate() {
|
| lib_dependencies.c_str()));
|
|
|
| // Shut down the llc subprocess.
|
| - RegisterReverseInterface(NULL);
|
| - llc_subprocess.reset(NULL);
|
| - if (SubprocessesShouldDie()) {
|
| - TranslateFailed("stopped by coordinator.");
|
| - return;
|
| - }
|
| + NaClXMutexLock(&subprocess_mu_);
|
| + llc_subprocess_active_ = false;
|
| + llc_subprocess_.reset(NULL);
|
| + NaClXMutexUnlock(&subprocess_mu_);
|
|
|
| if(!RunLdSubprocess(is_shared_library, soname, lib_dependencies)) {
|
| return;
|
| @@ -218,16 +227,7 @@ bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library,
|
| const nacl::string& lib_dependencies
|
| ) {
|
| ErrorInfo error_info;
|
| - nacl::scoped_ptr<NaClSubprocess> ld_subprocess(
|
| - StartSubprocess(PnaclUrls::GetLdUrl(), ld_manifest_, &error_info));
|
| - if (ld_subprocess == NULL) {
|
| - TranslateFailed("Link process could not be created: " +
|
| - error_info.message());
|
| - return false;
|
| - }
|
| - // Run LD.
|
| SrpcParams params;
|
| -
|
| // Reset object file for reading first.
|
| if (!obj_file_->Reset()) {
|
| TranslateFailed("Link process could not reset object file");
|
| @@ -235,12 +235,25 @@ bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library,
|
| }
|
| nacl::DescWrapper* ld_in_file = obj_file_->get_wrapper();
|
| nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper();
|
| - PluginReverseInterface* ld_reverse =
|
| - ld_subprocess->service_runtime()->rev_interface();
|
| - ld_reverse->AddQuotaManagedFile(nexe_file_->identifier(),
|
| - nexe_file_->write_file_io());
|
| - RegisterReverseInterface(ld_reverse);
|
| - if (!ld_subprocess->InvokeSrpcMethod("RunWithDefaultCommandLine",
|
| +
|
| + {
|
| + // Create LD process
|
| + nacl::MutexLocker ml(&subprocess_mu_);
|
| + ld_subprocess_.reset(
|
| + StartSubprocess(PnaclUrls::GetLdUrl(), ld_manifest_, &error_info));
|
| + if (ld_subprocess_ == NULL) {
|
| + TranslateFailed("Link process could not be created: " +
|
| + error_info.message());
|
| + return false;
|
| + }
|
| + ld_subprocess_active_ = true;
|
| + PluginReverseInterface* ld_reverse =
|
| + ld_subprocess_->service_runtime()->rev_interface();
|
| + ld_reverse->AddQuotaManagedFile(nexe_file_->identifier(),
|
| + nexe_file_->write_file_io());
|
| + }
|
| + // Run LD.
|
| + if (!ld_subprocess_->InvokeSrpcMethod("RunWithDefaultCommandLine",
|
| "hhiss",
|
| ¶ms,
|
| ld_in_file->desc(),
|
| @@ -254,12 +267,10 @@ bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library,
|
| PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n",
|
| this));
|
| // Shut down the ld subprocess.
|
| - RegisterReverseInterface(NULL);
|
| - ld_subprocess.reset(NULL);
|
| - if (SubprocessesShouldDie()) {
|
| - TranslateFailed("stopped by coordinator.");
|
| - return false;
|
| - }
|
| + NaClXMutexLock(&subprocess_mu_);
|
| + ld_subprocess_active_ = false;
|
| + ld_subprocess_.reset(NULL);
|
| + NaClXMutexUnlock(&subprocess_mu_);
|
| return true;
|
| }
|
|
|
| @@ -277,43 +288,32 @@ void PnaclTranslateThread::TranslateFailed(const nacl::string& error_string) {
|
| core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED);
|
| }
|
|
|
| -// This synchronization method (using the pointer directly in the
|
| -// translation thread, setting a copy here, and calling shutdown on the
|
| -// main thread) is safe only because only the translation thread sets
|
| -// the copy, and the shutdown method is thread-safe. This method must be
|
| -// called on the translation thread before any RPCs are called, and called
|
| -// again with NULL before the object is destroyed.
|
| -void PnaclTranslateThread::RegisterReverseInterface(
|
| - PluginReverseInterface *iface) {
|
| - nacl::MutexLocker ml(&subprocess_mu_);
|
| - current_rev_interface_ = iface;
|
| -}
|
| -
|
| -
|
| -bool PnaclTranslateThread::SubprocessesShouldDie() {
|
| - nacl::MutexLocker ml(&subprocess_mu_);
|
| - return subprocesses_should_die_;
|
| -}
|
| -
|
| -void PnaclTranslateThread::SetSubprocessesShouldDie() {
|
| - PLUGIN_PRINTF(("PnaclTranslateThread::SetSubprocessesShouldDie\n"));
|
| +void PnaclTranslateThread::AbortSubprocesses() {
|
| + PLUGIN_PRINTF(("PnaclTranslateThread::AbortSubprocesses\n"));
|
| NaClXMutexLock(&subprocess_mu_);
|
| - subprocesses_should_die_ = true;
|
| - if (current_rev_interface_) {
|
| - current_rev_interface_->ShutDown();
|
| - current_rev_interface_ = NULL;
|
| + if (llc_subprocess_ != NULL && llc_subprocess_active_) {
|
| + llc_subprocess_->service_runtime()->Shutdown();
|
| + llc_subprocess_active_ = false;
|
| + }
|
| + if (ld_subprocess_ != NULL && ld_subprocess_active_) {
|
| + ld_subprocess_->service_runtime()->Shutdown();
|
| + ld_subprocess_active_ = false;
|
| }
|
| NaClXMutexUnlock(&subprocess_mu_);
|
| nacl::MutexLocker ml(&cond_mu_);
|
| done_ = true;
|
| + // Free all buffered bitcode chunks
|
| + data_buffers_.clear();
|
| NaClXCondVarSignal(&buffer_cond_);
|
| }
|
|
|
| PnaclTranslateThread::~PnaclTranslateThread() {
|
| PLUGIN_PRINTF(("~PnaclTranslateThread (translate_thread=%p)\n", this));
|
| - SetSubprocessesShouldDie();
|
| + AbortSubprocesses();
|
| NaClThreadJoin(translate_thread_.get());
|
| PLUGIN_PRINTF(("~PnaclTranslateThread joined\n"));
|
| + NaClCondVarDtor(&buffer_cond_);
|
| + NaClMutexDtor(&cond_mu_);
|
| NaClMutexDtor(&subprocess_mu_);
|
| }
|
|
|
|
|