Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(307)

Unified Diff: ppapi/native_client/src/trusted/plugin/service_runtime.cc

Issue 338353008: NaCl: clean up nexe loading logic in trusted plugin. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase + resolve conflicts Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/service_runtime.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/native_client/src/trusted/plugin/service_runtime.cc
diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
index f2d0230be3ec1b140f24cd44e1cf2805aa472510..5235e238acc23e30c4424ae3314b7b8e47b0ed3b 100644
--- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc
+++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
@@ -346,30 +346,6 @@ int64_t PluginReverseInterface::RequestQuotaForWrite(
return bytes_to_write;
}
-// Thin wrapper for the arguments of LoadNexeAndStart(), as WeakRefNewCallback
-// can take only one argument. Also, this dtor has the responsibility to invoke
-// callbacks on destruction.
-struct ServiceRuntime::LoadNexeAndStartData {
- explicit LoadNexeAndStartData(const pp::CompletionCallback& callback)
- : callback(callback) {
- }
-
- ~LoadNexeAndStartData() {
- // We must call the callbacks here if they are not yet called, otherwise
- // the resource would be leaked.
- if (callback.pp_completion_callback().func)
- callback.RunAndClear(PP_ERROR_ABORTED);
- }
-
- // On success path, this must be invoked manually. Otherwise the dtor would
- // invoke callbacks with error code unexpectedly.
- void Clear() {
- callback = pp::CompletionCallback();
- }
-
- pp::CompletionCallback callback;
-};
-
ServiceRuntime::ServiceRuntime(Plugin* plugin,
bool main_service_runtime,
bool uses_nonsfi_mode,
@@ -383,56 +359,13 @@ ServiceRuntime::ServiceRuntime(Plugin* plugin,
rev_interface_(new PluginReverseInterface(anchor_, plugin, this,
init_done_cb, crash_cb)),
start_sel_ldr_done_(false),
- nexe_started_(false) {
+ start_nexe_done_(false),
+ nexe_started_ok_(false) {
NaClSrpcChannelInitialize(&command_channel_);
NaClXMutexCtor(&mu_);
NaClXCondVarCtor(&cond_);
}
-void ServiceRuntime::LoadNexeAndStartAfterLoadModule(
- LoadNexeAndStartData* data, int32_t pp_error) {
- if (pp_error != PP_OK) {
- DidLoadNexeAndStart(data, pp_error);
- return;
- }
-
- // Here, LoadModule is successfully done. So the remaining task is just
- // calling StartModule(), here.
- DidLoadNexeAndStart(data, StartModule() ? PP_OK : PP_ERROR_FAILED);
-}
-
-void ServiceRuntime::DidLoadNexeAndStart(
- LoadNexeAndStartData* data, int32_t pp_error) {
- if (pp_error == PP_OK) {
- NaClLog(4, "ServiceRuntime::LoadNexeAndStart (success)\n");
- } else {
- // On a load failure the service runtime does not crash itself to
- // avoid a race where the no-more-senders error on the reverse
- // channel esrvice thread might cause the crash-detection logic to
- // kick in before the start_module RPC reply has been received. So
- // we induce a service runtime crash here. We do not release
- // subprocess_ since it's needed to collect crash log output after
- // the error is reported.
- Log(LOG_FATAL, "reap logs");
- if (NULL == reverse_service_) {
- // No crash detector thread.
- NaClLog(LOG_ERROR, "scheduling to get crash log\n");
- // Invoking rev_interface's method is workaround to avoid crash_cb
- // gets called twice or more. We should clean this up later.
- rev_interface_->ReportCrash();
- NaClLog(LOG_ERROR, "should fire soon\n");
- } else {
- NaClLog(LOG_ERROR, "Reverse service thread will pick up crash log\n");
- }
- }
-
- pp::Module::Get()->core()->CallOnMainThread(0, data->callback, pp_error);
-
- // Because the ownership of data is taken by caller, we must clear it
- // manually here. Otherwise, its dtor invokes callbacks again.
- data->Clear();
-}
-
bool ServiceRuntime::SetupCommandChannel() {
NaClLog(4, "ServiceRuntime::SetupCommand (this=%p, subprocess=%p)\n",
static_cast<void*>(this),
@@ -454,45 +387,6 @@ bool ServiceRuntime::SetupCommandChannel() {
return true;
}
-void ServiceRuntime::LoadModule(PP_NaClFileInfo file_info,
- pp::CompletionCallback callback) {
- if (uses_nonsfi_mode_) {
- // In non-SFI mode, loading is done a part of LaunchSelLdr.
- DidLoadModule(callback, PP_OK);
- return;
- }
-
- NaClFileInfo nacl_file_info;
- nacl_file_info.desc = ConvertFileDescriptor(file_info.handle, true);
- nacl_file_info.file_token.lo = file_info.token_lo;
- nacl_file_info.file_token.hi = file_info.token_hi;
- NaClDesc* desc = NaClDescIoFromFileInfo(nacl_file_info, O_RDONLY);
- if (desc == NULL) {
- DidLoadModule(callback, PP_ERROR_FAILED);
- return;
- }
-
- // We don't use a scoped_ptr here since we would immediately release the
- // DescWrapper to LoadModule().
- nacl::DescWrapper* wrapper =
- plugin_->wrapper_factory()->MakeGenericCleanup(desc);
-
- // TODO(teravest, hidehiko): Replace this by Chrome IPC.
- bool result = subprocess_->LoadModule(&command_channel_, wrapper);
- DidLoadModule(callback, result ? PP_OK : PP_ERROR_FAILED);
-}
-
-void ServiceRuntime::DidLoadModule(pp::CompletionCallback callback,
- int32_t pp_error) {
- if (pp_error != PP_OK) {
- ErrorInfo error_info;
- error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL,
- "ServiceRuntime: load module failed");
- plugin_->ReportLoadError(error_info);
- }
- callback.Run(pp_error);
-}
-
bool ServiceRuntime::InitReverseService() {
if (uses_nonsfi_mode_) {
// In non-SFI mode, no reverse service is set up. Just returns success.
@@ -667,41 +561,100 @@ void ServiceRuntime::SignalStartSelLdrDone() {
NaClXCondVarSignal(&cond_);
}
-void ServiceRuntime::WaitForNexeStart() {
+bool ServiceRuntime::WaitForNexeStart() {
nacl::MutexLocker take(&mu_);
- while (!nexe_started_)
+ while (!start_nexe_done_)
NaClXCondVarWait(&cond_, &mu_);
- // Reset nexe_started_ here in case we run again.
- nexe_started_ = false;
+ return nexe_started_ok_;
}
-void ServiceRuntime::SignalNexeStarted() {
+void ServiceRuntime::SignalNexeStarted(bool ok) {
nacl::MutexLocker take(&mu_);
- nexe_started_ = true;
+ start_nexe_done_ = true;
+ nexe_started_ok_ = ok;
NaClXCondVarSignal(&cond_);
}
-void ServiceRuntime::LoadNexeAndStart(PP_NaClFileInfo file_info,
- const pp::CompletionCallback& callback) {
+void ServiceRuntime::LoadNexeAndStart(PP_NaClFileInfo file_info) {
NaClLog(4, "ServiceRuntime::LoadNexeAndStart (handle_valid=%d "
"token_lo=%" NACL_PRIu64 " token_hi=%" NACL_PRIu64 ")\n",
file_info.handle != PP_kInvalidFileHandle,
file_info.token_lo,
file_info.token_hi);
- nacl::scoped_ptr<LoadNexeAndStartData> data(
- new LoadNexeAndStartData(callback));
- if (!SetupCommandChannel() || !InitReverseService()) {
- DidLoadNexeAndStart(data.get(), PP_ERROR_FAILED);
- return;
+ bool ok = LoadNexeAndStartInternal(file_info);
+ if (ok) {
+ NaClLog(4, "ServiceRuntime::LoadNexeAndStart (success)\n");
+ } else {
+ ReapLogs();
+ }
+ // This only matters if a background thread is waiting, but we signal in all
+ // cases to simplify the code.
+ SignalNexeStarted(ok);
+}
+
+bool ServiceRuntime::LoadNexeAndStartInternal(
+ const PP_NaClFileInfo& file_info) {
+ if(!SetupCommandChannel()) {
+ return false;
+ }
+ if (!InitReverseService()) {
+ return false;
+ }
+ if (!LoadModule(file_info)) {
+ ErrorInfo error_info;
+ error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL,
+ "ServiceRuntime: load module failed");
+ plugin_->ReportLoadError(error_info);
+ return false;
+ }
+ if (!StartModule()) {
+ return false;
}
+ return true;
+}
- LoadModule(
- file_info,
- WeakRefNewCallback(anchor_,
- this,
- &ServiceRuntime::LoadNexeAndStartAfterLoadModule,
- data.release())); // Delegate the ownership.
+bool ServiceRuntime::LoadModule(const PP_NaClFileInfo& file_info) {
+ if (uses_nonsfi_mode_) {
+ // In non-SFI mode, loading is done a part of LaunchSelLdr.
+ return true;
+ }
+
+ NaClFileInfo nacl_file_info;
+ nacl_file_info.desc = ConvertFileDescriptor(file_info.handle, true);
+ nacl_file_info.file_token.lo = file_info.token_lo;
+ nacl_file_info.file_token.hi = file_info.token_hi;
+ NaClDesc* desc = NaClDescIoFromFileInfo(nacl_file_info, O_RDONLY);
+ if (desc == NULL) {
+ return false;
+ }
+ // We don't use a scoped_ptr here since we would immediately release the
+ // DescWrapper to LoadModule().
+ nacl::DescWrapper* wrapper =
+ plugin_->wrapper_factory()->MakeGenericCleanup(desc);
+ // TODO(teravest, hidehiko): Replace this by Chrome IPC.
+ return subprocess_->LoadModule(&command_channel_, wrapper);
+}
+
+void ServiceRuntime::ReapLogs() {
+ // On a load failure the service runtime does not crash itself to
+ // avoid a race where the no-more-senders error on the reverse
+ // channel service thread might cause the crash-detection logic to
+ // kick in before the start_module RPC reply has been received. So
+ // we induce a service runtime crash here. We do not release
+ // subprocess_ since it's needed to collect crash log output after
+ // the error is reported.
+ RemoteLog(LOG_FATAL, "reap logs\n");
+ if (NULL == reverse_service_) {
+ // No crash detector thread.
+ NaClLog(LOG_ERROR, "scheduling to get crash log\n");
+ // Invoking rev_interface's method is workaround to avoid crash_cb
+ // gets called twice or more. We should clean this up later.
+ rev_interface_->ReportCrash();
+ NaClLog(LOG_ERROR, "should fire soon\n");
+ } else {
+ NaClLog(LOG_ERROR, "Reverse service thread will pick up crash log\n");
+ }
}
SrpcClient* ServiceRuntime::SetupAppChannel() {
@@ -722,7 +675,7 @@ SrpcClient* ServiceRuntime::SetupAppChannel() {
}
}
-bool ServiceRuntime::Log(int severity, const nacl::string& msg) {
+bool ServiceRuntime::RemoteLog(int severity, const nacl::string& msg) {
NaClSrpcResultCodes rpc_result =
NaClSrpcInvokeBySignature(&command_channel_,
"log:is:",
« no previous file with comments | « ppapi/native_client/src/trusted/plugin/service_runtime.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698