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

Side by Side Diff: ppapi/native_client/src/trusted/plugin/service_runtime.cc

Issue 870923004: NaCl: Remove now-unneeded SRPC reverse service code (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #define NACL_LOG_MODULE_NAME "Plugin_ServiceRuntime" 7 #define NACL_LOG_MODULE_NAME "Plugin_ServiceRuntime"
8 8
9 #include "ppapi/native_client/src/trusted/plugin/service_runtime.h" 9 #include "ppapi/native_client/src/trusted/plugin/service_runtime.h"
10 10
(...skipping 21 matching lines...) Expand all
32 #include "ppapi/c/pp_errors.h" 32 #include "ppapi/c/pp_errors.h"
33 #include "ppapi/cpp/core.h" 33 #include "ppapi/cpp/core.h"
34 #include "ppapi/cpp/completion_callback.h" 34 #include "ppapi/cpp/completion_callback.h"
35 35
36 #include "ppapi/native_client/src/trusted/plugin/plugin.h" 36 #include "ppapi/native_client/src/trusted/plugin/plugin.h"
37 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" 37 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
38 #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h" 38 #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h"
39 #include "ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h" 39 #include "ppapi/native_client/src/trusted/plugin/sel_ldr_launcher_chrome.h"
40 #include "ppapi/native_client/src/trusted/plugin/srpc_client.h" 40 #include "ppapi/native_client/src/trusted/plugin/srpc_client.h"
41 #include "ppapi/native_client/src/trusted/plugin/utility.h" 41 #include "ppapi/native_client/src/trusted/plugin/utility.h"
42 #include "ppapi/native_client/src/trusted/weak_ref/call_on_main_thread.h"
43 42
44 namespace plugin { 43 namespace plugin {
45 44
46 OpenManifestEntryResource::~OpenManifestEntryResource() {
47 }
48
49 PluginReverseInterface::PluginReverseInterface(
50 nacl::WeakRefAnchor* anchor,
51 PP_Instance pp_instance,
52 ServiceRuntime* service_runtime)
53 : anchor_(anchor),
54 pp_instance_(pp_instance),
55 service_runtime_(service_runtime),
56 shutting_down_(false) {
57 NaClXMutexCtor(&mu_);
58 NaClXCondVarCtor(&cv_);
59 }
60
61 PluginReverseInterface::~PluginReverseInterface() {
62 NaClCondVarDtor(&cv_);
63 NaClMutexDtor(&mu_);
64 }
65
66 void PluginReverseInterface::ShutDown() {
67 NaClLog(4, "PluginReverseInterface::Shutdown: entered\n");
68 nacl::MutexLocker take(&mu_);
69 shutting_down_ = true;
70 NaClXCondVarBroadcast(&cv_);
71 NaClLog(4, "PluginReverseInterface::Shutdown: broadcasted, exiting\n");
72 }
73
74 void PluginReverseInterface::DoPostMessage(std::string message) {
75 // This feature is no longer used.
76 // TODO(teravest): Remove this once this is gone from nacl::ReverseInterface.
77 }
78
79 void PluginReverseInterface::StartupInitializationComplete() {
80 // This is no longer used.
81 }
82
83 // TODO(bsy): OpenManifestEntry should use the manifest to ResolveKey
84 // and invoke StreamAsFile with a completion callback that invokes
85 // GetPOSIXFileDesc.
86 bool PluginReverseInterface::OpenManifestEntry(std::string url_key,
87 struct NaClFileInfo* info) {
88 // This method should only ever be called from the PNaCl translator, as the
89 // IRT is not available there.
90 // TODO(teravest): Remove support for OpenManifestEntry here once
91 // crbug.com/302078 is resolved.
92 if (service_runtime_->main_service_runtime()) {
93 NaClLog(LOG_ERROR,
94 "OpenManifestEntry should only be used by PNaCl translator.\n");
95 return false;
96 }
97
98 bool op_complete = false; // NB: mu_ and cv_ also controls access to this!
99 // The to_open object is owned by the weak ref callback. Because this function
100 // waits for the callback to finish, the to_open object will be deallocated on
101 // the main thread before this function can return. The pointers it contains
102 // to stack variables will not leak.
103 OpenManifestEntryResource* to_open =
104 new OpenManifestEntryResource(url_key, info, &op_complete);
105 CHECK(to_open != NULL);
106 NaClLog(4, "PluginReverseInterface::OpenManifestEntry: %s\n",
107 url_key.c_str());
108 // This assumes we are not on the main thread. If false, we deadlock.
109 plugin::WeakRefCallOnMainThread(
110 anchor_,
111 0,
112 this,
113 &plugin::PluginReverseInterface::OpenManifestEntry_MainThreadContinuation,
114 to_open);
115 NaClLog(4,
116 "PluginReverseInterface::OpenManifestEntry:"
117 " waiting on main thread\n");
118
119 {
120 nacl::MutexLocker take(&mu_);
121 while (!shutting_down_ && !op_complete)
122 NaClXCondVarWait(&cv_, &mu_);
123 NaClLog(4, "PluginReverseInterface::OpenManifestEntry: done!\n");
124 if (shutting_down_) {
125 NaClLog(4,
126 "PluginReverseInterface::OpenManifestEntry:"
127 " plugin is shutting down\n");
128 return false;
129 }
130 }
131
132 // info->desc has the returned descriptor if successful, else -1.
133
134 // The caller is responsible for not closing info->desc. If it is
135 // closed prematurely, then another open could re-use the OS
136 // descriptor, confusing the opened_ map. If the caller is going to
137 // want to make a NaClDesc object and transfer it etc., then the
138 // caller should DUP the descriptor (but remember the original
139 // value) for use by the NaClDesc object, which closes when the
140 // object is destroyed.
141 NaClLog(4,
142 "PluginReverseInterface::OpenManifestEntry: info->desc = %d\n",
143 info->desc);
144 if (info->desc == -1) {
145 // TODO(bsy,ncbray): what else should we do with the error? This
146 // is a runtime error that may simply be a programming error in
147 // the untrusted code, or it may be something else wrong w/ the
148 // manifest.
149 NaClLog(4, "OpenManifestEntry: failed for key %s", url_key.c_str());
150 }
151 return true;
152 }
153
154 // Transfer point from OpenManifestEntry() which runs on the main thread
155 // (Some PPAPI actions -- like StreamAsFile -- can only run on the main thread).
156 // OpenManifestEntry() is waiting on a condvar for this continuation to
157 // complete. We Broadcast and awaken OpenManifestEntry() whenever we are done
158 // either here, or in a later MainThreadContinuation step, if there are
159 // multiple steps.
160 void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
161 OpenManifestEntryResource* p,
162 int32_t err) {
163 UNREFERENCED_PARAMETER(err);
164 // CallOnMainThread continuations always called with err == PP_OK.
165
166 NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n");
167
168 // Because p is owned by the callback of this invocation, so it is necessary
169 // to create another instance.
170 OpenManifestEntryResource* open_cont = new OpenManifestEntryResource(*p);
171 pp::CompletionCallback stream_cc = WeakRefNewCallback(
172 anchor_,
173 this,
174 &PluginReverseInterface::StreamAsFile_MainThreadContinuation,
175 open_cont);
176
177 GetNaClInterface()->OpenManifestEntry(
178 pp_instance_,
179 PP_FromBool(!service_runtime_->main_service_runtime()),
180 p->url.c_str(),
181 &open_cont->pp_file_info,
182 stream_cc.pp_completion_callback());
183 // p is deleted automatically.
184 }
185
186 void PluginReverseInterface::StreamAsFile_MainThreadContinuation(
187 OpenManifestEntryResource* p,
188 int32_t result) {
189 NaClLog(4, "Entered StreamAsFile_MainThreadContinuation\n");
190 {
191 nacl::MutexLocker take(&mu_);
192 if (result == PP_OK) {
193 // We downloaded this file to temporary storage for this plugin; it's
194 // reasonable to provide a file descriptor with write access.
195 p->file_info->desc = ConvertFileDescriptor(p->pp_file_info.handle, false);
196 p->file_info->file_token.lo = p->pp_file_info.token_lo;
197 p->file_info->file_token.hi = p->pp_file_info.token_hi;
198 NaClLog(4,
199 "StreamAsFile_MainThreadContinuation: PP_OK, desc %d\n",
200 p->file_info->desc);
201 } else {
202 NaClLog(
203 4,
204 "StreamAsFile_MainThreadContinuation: !PP_OK, setting desc -1\n");
205 p->file_info->desc = -1;
206 }
207 *p->op_complete_ptr = true;
208 NaClXCondVarBroadcast(&cv_);
209 }
210 }
211
212 void PluginReverseInterface::ReportCrash() {
213 // This is now handled through Chromium IPC.
214 }
215
216 void PluginReverseInterface::ReportExitStatus(int exit_status) {
217 // We do nothing here; reporting exit status is handled through a separate
218 // embedder interface.
219 }
220
221 int64_t PluginReverseInterface::RequestQuotaForWrite(
222 std::string file_id, int64_t offset, int64_t bytes_to_write) {
223 return bytes_to_write;
224 }
225
226 ServiceRuntime::ServiceRuntime(Plugin* plugin, 45 ServiceRuntime::ServiceRuntime(Plugin* plugin,
227 PP_Instance pp_instance, 46 PP_Instance pp_instance,
228 bool main_service_runtime, 47 bool main_service_runtime,
229 bool uses_nonsfi_mode) 48 bool uses_nonsfi_mode)
230 : plugin_(plugin), 49 : plugin_(plugin),
231 pp_instance_(pp_instance), 50 pp_instance_(pp_instance),
232 main_service_runtime_(main_service_runtime), 51 main_service_runtime_(main_service_runtime),
233 uses_nonsfi_mode_(uses_nonsfi_mode), 52 uses_nonsfi_mode_(uses_nonsfi_mode),
234 reverse_service_(NULL),
235 anchor_(new nacl::WeakRefAnchor()),
236 rev_interface_(new PluginReverseInterface(anchor_, pp_instance, this)),
237 start_sel_ldr_done_(false), 53 start_sel_ldr_done_(false),
238 sel_ldr_wait_timed_out_(false), 54 sel_ldr_wait_timed_out_(false),
239 start_nexe_done_(false), 55 start_nexe_done_(false),
240 nexe_started_ok_(false), 56 nexe_started_ok_(false),
241 bootstrap_channel_(NACL_INVALID_HANDLE) { 57 bootstrap_channel_(NACL_INVALID_HANDLE) {
242 NaClSrpcChannelInitialize(&command_channel_); 58 NaClSrpcChannelInitialize(&command_channel_);
243 NaClXMutexCtor(&mu_); 59 NaClXMutexCtor(&mu_);
244 NaClXCondVarCtor(&cond_); 60 NaClXCondVarCtor(&cond_);
245 } 61 }
246 62
(...skipping 13 matching lines...) Expand all
260 if (!subprocess_->SetupCommand(&command_channel_)) { 76 if (!subprocess_->SetupCommand(&command_channel_)) {
261 ErrorInfo error_info; 77 ErrorInfo error_info;
262 error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL, 78 error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_CMD_CHANNEL,
263 "ServiceRuntime: command channel creation failed"); 79 "ServiceRuntime: command channel creation failed");
264 ReportLoadError(error_info); 80 ReportLoadError(error_info);
265 return false; 81 return false;
266 } 82 }
267 return true; 83 return true;
268 } 84 }
269 85
270 bool ServiceRuntime::InitReverseService() {
271 if (uses_nonsfi_mode_) {
272 // In non-SFI mode, no reverse service is set up. Just returns success.
273 return true;
274 }
275
276 // Hook up the reverse service channel. We are the IMC client, but
277 // provide SRPC service.
278 NaClDesc* out_conn_cap;
279 NaClSrpcResultCodes rpc_result =
280 NaClSrpcInvokeBySignature(&command_channel_,
281 "reverse_setup::h",
282 &out_conn_cap);
283
284 if (NACL_SRPC_RESULT_OK != rpc_result) {
285 ErrorInfo error_info;
286 error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_REV_SETUP,
287 "ServiceRuntime: reverse setup rpc failed");
288 ReportLoadError(error_info);
289 return false;
290 }
291 // Get connection capability to service runtime where the IMC
292 // server/SRPC client is waiting for a rendezvous.
293 NaClLog(4, "ServiceRuntime: got 0x%" NACL_PRIxPTR "\n",
294 (uintptr_t) out_conn_cap);
295 nacl::DescWrapper* conn_cap = plugin_->wrapper_factory()->MakeGenericCleanup(
296 out_conn_cap);
297 if (conn_cap == NULL) {
298 ErrorInfo error_info;
299 error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_WRAPPER,
300 "ServiceRuntime: wrapper allocation failure");
301 ReportLoadError(error_info);
302 return false;
303 }
304 out_conn_cap = NULL; // ownership passed
305 NaClLog(4, "ServiceRuntime::InitReverseService: starting reverse service\n");
306 reverse_service_ = new nacl::ReverseService(conn_cap, rev_interface_->Ref());
307 if (!reverse_service_->Start()) {
308 ErrorInfo error_info;
309 error_info.SetReport(PP_NACL_ERROR_SEL_LDR_COMMUNICATION_REV_SERVICE,
310 "ServiceRuntime: starting reverse services failed");
311 ReportLoadError(error_info);
312 return false;
313 }
314 return true;
315 }
316
317 bool ServiceRuntime::StartModule() { 86 bool ServiceRuntime::StartModule() {
318 // start the module. otherwise we cannot connect for multimedia 87 // start the module. otherwise we cannot connect for multimedia
319 // subsystem since that is handled by user-level code (not secure!) 88 // subsystem since that is handled by user-level code (not secure!)
320 // in libsrpc. 89 // in libsrpc.
321 int load_status = -1; 90 int load_status = -1;
322 if (uses_nonsfi_mode_) { 91 if (uses_nonsfi_mode_) {
323 // In non-SFI mode, we don't need to call start_module SRPC to launch 92 // In non-SFI mode, we don't need to call start_module SRPC to launch
324 // the plugin. 93 // the plugin.
325 load_status = LOAD_OK; 94 load_status = LOAD_OK;
326 } else { 95 } else {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 ReapLogs(); 221 ReapLogs();
453 } 222 }
454 // This only matters if a background thread is waiting, but we signal in all 223 // This only matters if a background thread is waiting, but we signal in all
455 // cases to simplify the code. 224 // cases to simplify the code.
456 SignalNexeStarted(ok); 225 SignalNexeStarted(ok);
457 } 226 }
458 227
459 bool ServiceRuntime::StartNexeInternal() { 228 bool ServiceRuntime::StartNexeInternal() {
460 if (!SetupCommandChannel()) 229 if (!SetupCommandChannel())
461 return false; 230 return false;
462 if (!InitReverseService())
463 return false;
464 return StartModule(); 231 return StartModule();
465 } 232 }
466 233
467 void ServiceRuntime::ReapLogs() { 234 void ServiceRuntime::ReapLogs() {
468 // TODO(teravest): We should allow the NaCl process to crash itself when a 235 // TODO(teravest): We should allow the NaCl process to crash itself when a
469 // module fails to start, and remove the call to RemoteLog() here. The 236 // module fails to start, and remove the call to RemoteLog() here. The
470 // reverse channel is no longer needed for crash reporting. 237 // reverse channel is no longer needed for crash reporting.
471 // 238 //
472 // The reasoning behind the current code behavior follows: 239 // The reasoning behind the current code behavior follows:
473 // On a load failure the NaCl process does not crash itself to 240 // On a load failure the NaCl process does not crash itself to
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 bool ServiceRuntime::RemoteLog(int severity, const std::string& msg) { 276 bool ServiceRuntime::RemoteLog(int severity, const std::string& msg) {
510 NaClSrpcResultCodes rpc_result = 277 NaClSrpcResultCodes rpc_result =
511 NaClSrpcInvokeBySignature(&command_channel_, 278 NaClSrpcInvokeBySignature(&command_channel_,
512 "log:is:", 279 "log:is:",
513 severity, 280 severity,
514 strdup(msg.c_str())); 281 strdup(msg.c_str()));
515 return (NACL_SRPC_RESULT_OK == rpc_result); 282 return (NACL_SRPC_RESULT_OK == rpc_result);
516 } 283 }
517 284
518 void ServiceRuntime::Shutdown() { 285 void ServiceRuntime::Shutdown() {
519 rev_interface_->ShutDown();
520 anchor_->Abandon();
521 // Abandon callbacks, tell service threads to quit if they were 286 // Abandon callbacks, tell service threads to quit if they were
522 // blocked waiting for main thread operations to finish. Note that 287 // blocked waiting for main thread operations to finish. Note that
523 // some callbacks must still await their completion event, e.g., 288 // some callbacks must still await their completion event, e.g.,
524 // CallOnMainThread must still wait for the time out, or I/O events 289 // CallOnMainThread must still wait for the time out, or I/O events
525 // must finish, so resources associated with pending events cannot 290 // must finish, so resources associated with pending events cannot
526 // be deallocated. 291 // be deallocated.
527 292
528 // Note that this does waitpid() to get rid of any zombie subprocess. 293 // Note that this does waitpid() to get rid of any zombie subprocess.
529 subprocess_.reset(NULL); 294 subprocess_.reset(NULL);
530 295
531 NaClSrpcDtor(&command_channel_); 296 NaClSrpcDtor(&command_channel_);
532
533 // subprocess_ has been shut down, but threads waiting on messages
534 // from the service runtime may not have noticed yet. The low-level
535 // NaClSimpleRevService code takes care to refcount the data objects
536 // that it needs, and reverse_service_ is also refcounted. We wait
537 // for the service threads to get their EOF indications.
538 if (reverse_service_ != NULL) {
539 reverse_service_->WaitForServiceThreadsToExit();
540 reverse_service_->Unref();
541 reverse_service_ = NULL;
542 }
543 } 297 }
544 298
545 ServiceRuntime::~ServiceRuntime() { 299 ServiceRuntime::~ServiceRuntime() {
546 NaClLog(4, "ServiceRuntime::~ServiceRuntime (this=%p)\n", 300 NaClLog(4, "ServiceRuntime::~ServiceRuntime (this=%p)\n",
547 static_cast<void*>(this)); 301 static_cast<void*>(this));
548 // We do this just in case Shutdown() was not called. 302 // We do this just in case Shutdown() was not called.
549 subprocess_.reset(NULL); 303 subprocess_.reset(NULL);
550 if (reverse_service_ != NULL)
551 reverse_service_->Unref();
552 304
553 rev_interface_->Unref();
554
555 anchor_->Unref();
556 NaClCondVarDtor(&cond_); 305 NaClCondVarDtor(&cond_);
557 NaClMutexDtor(&mu_); 306 NaClMutexDtor(&mu_);
558 } 307 }
559 308
560 } // namespace plugin 309 } // namespace plugin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698