2 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
7 #define NACL_LOG_MODULE_NAME "Plugin_ServiceRuntime"
9 #include "components/nacl/renderer/plugin/service_runtime.h"
15 #include "base/compiler_specific.h"
16 #include "components/nacl/renderer/plugin/plugin.h"
17 #include "components/nacl/renderer/plugin/plugin_error.h"
18 #include "components/nacl/renderer/plugin/sel_ldr_launcher_chrome.h"
19 #include "components/nacl/renderer/plugin/srpc_client.h"
20 #include "components/nacl/renderer/plugin/utility.h"
21 #include "native_client/src/include/nacl_macros.h"
22 #include "native_client/src/include/nacl_scoped_ptr.h"
23 #include "native_client/src/include/portability_io.h"
24 #include "native_client/src/include/portability_string.h"
25 #include "native_client/src/public/imc_types.h"
26 #include "native_client/src/shared/platform/nacl_check.h"
27 #include "native_client/src/shared/platform/nacl_log.h"
28 #include "native_client/src/trusted/nonnacl_util/sel_ldr_launcher.h"
29 #include "native_client/src/trusted/service_runtime/nacl_error_code.h"
30 #include "ppapi/c/pp_errors.h"
31 #include "ppapi/cpp/completion_callback.h"
32 #include "ppapi/cpp/core.h"
36 ServiceRuntime::ServiceRuntime(Plugin
* plugin
,
37 PP_Instance pp_instance
,
38 bool main_service_runtime
,
39 bool uses_nonsfi_mode
)
41 pp_instance_(pp_instance
),
42 main_service_runtime_(main_service_runtime
),
43 uses_nonsfi_mode_(uses_nonsfi_mode
),
44 bootstrap_channel_(NACL_INVALID_HANDLE
) {
47 bool ServiceRuntime::SetupCommandChannel() {
48 NaClLog(4, "ServiceRuntime::SetupCommand (this=%p, subprocess=%p)\n",
49 static_cast<void*>(this),
50 static_cast<void*>(subprocess_
.get()));
51 // Set up the bootstrap channel in our subprocess so that we can establish
53 subprocess_
->set_channel(bootstrap_channel_
);
55 if (uses_nonsfi_mode_
) {
56 // In non-SFI mode, no SRPC is used. Just skips and returns success.
60 if (!subprocess_
->ConnectBootstrapSocket()) {
62 error_info
.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL
,
63 "ServiceRuntime: ConnectBootstrapSocket() failed");
64 ReportLoadError(error_info
);
67 if (!subprocess_
->RetrieveSockAddr()) {
69 error_info
.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL
,
70 "ServiceRuntime: RetrieveSockAddr() failed");
71 ReportLoadError(error_info
);
77 void ServiceRuntime::StartSelLdr(const SelLdrStartParams
& params
,
78 pp::CompletionCallback callback
) {
79 NaClLog(4, "ServiceRuntime::Start\n");
81 nacl::scoped_ptr
<SelLdrLauncherChrome
>
82 tmp_subprocess(new SelLdrLauncherChrome());
83 if (NULL
== tmp_subprocess
.get()) {
84 NaClLog(LOG_ERROR
, "ServiceRuntime::Start (subprocess create failed)\n");
87 PP_NACL_ERROR_SEL_LDR_CREATE_LAUNCHER
,
88 "ServiceRuntime: failed to create sel_ldr launcher");
89 ReportLoadError(error_info
);
90 pp::Module::Get()->core()->CallOnMainThread(0, callback
, PP_ERROR_FAILED
);
94 GetNaClInterface()->LaunchSelLdr(
96 PP_FromBool(main_service_runtime_
),
99 PP_FromBool(uses_nonsfi_mode_
),
102 callback
.pp_completion_callback());
103 subprocess_
.reset(tmp_subprocess
.release());
106 void ServiceRuntime::StartNexe() {
107 bool ok
= SetupCommandChannel();
109 NaClLog(4, "ServiceRuntime::StartNexe (success)\n");
113 void ServiceRuntime::ReportLoadError(const ErrorInfo
& error_info
) {
114 if (main_service_runtime_
) {
115 plugin_
->ReportLoadError(error_info
);
119 SrpcClient
* ServiceRuntime::SetupAppChannel() {
120 NaClLog(4, "ServiceRuntime::SetupAppChannel (subprocess_=%p)\n",
121 reinterpret_cast<void*>(subprocess_
.get()));
122 nacl::DescWrapper
* connect_desc
= subprocess_
->socket_addr()->Connect();
123 if (NULL
== connect_desc
) {
124 NaClLog(LOG_ERROR
, "ServiceRuntime::SetupAppChannel (connect failed)\n");
127 NaClLog(4, "ServiceRuntime::SetupAppChannel (connect_desc=%p)\n",
128 static_cast<void*>(connect_desc
));
129 SrpcClient
* srpc_client
= SrpcClient::New(connect_desc
);
130 NaClLog(4, "ServiceRuntime::SetupAppChannel (srpc_client=%p)\n",
131 static_cast<void*>(srpc_client
));
137 void ServiceRuntime::Shutdown() {
138 // Abandon callbacks, tell service threads to quit if they were
139 // blocked waiting for main thread operations to finish. Note that
140 // some callbacks must still await their completion event, e.g.,
141 // CallOnMainThread must still wait for the time out, or I/O events
142 // must finish, so resources associated with pending events cannot
145 // Note that this does waitpid() to get rid of any zombie subprocess.
146 subprocess_
.reset(NULL
);
149 ServiceRuntime::~ServiceRuntime() {
150 NaClLog(4, "ServiceRuntime::~ServiceRuntime (this=%p)\n",
151 static_cast<void*>(this));
152 // We do this just in case Shutdown() was not called.
153 subprocess_
.reset(NULL
);
156 } // namespace plugin