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

Side by Side Diff: components/nacl/renderer/plugin/pnacl_translate_thread.cc

Issue 1512733003: PNaCl: Use Chrome IPC to talk to the linker process, instead of SRPC (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Review Created 4 years, 12 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 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/nacl/renderer/plugin/pnacl_translate_thread.h" 5 #include "components/nacl/renderer/plugin/pnacl_translate_thread.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "components/nacl/renderer/plugin/plugin.h" 11 #include "components/nacl/renderer/plugin/plugin.h"
12 #include "components/nacl/renderer/plugin/plugin_error.h" 12 #include "components/nacl/renderer/plugin/plugin_error.h"
13 #include "components/nacl/renderer/plugin/srpc_params.h" 13 #include "components/nacl/renderer/plugin/srpc_params.h"
14 #include "components/nacl/renderer/plugin/temporary_file.h" 14 #include "components/nacl/renderer/plugin/temporary_file.h"
15 #include "components/nacl/renderer/plugin/utility.h" 15 #include "components/nacl/renderer/plugin/utility.h"
16 #include "content/public/common/sandbox_init.h"
16 #include "native_client/src/shared/platform/nacl_sync_raii.h" 17 #include "native_client/src/shared/platform/nacl_sync_raii.h"
17 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" 18 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
19 #include "ppapi/c/ppb_file_io.h"
18 #include "ppapi/cpp/var.h" 20 #include "ppapi/cpp/var.h"
21 #include "ppapi/proxy/ppapi_messages.h"
19 22
20 namespace plugin { 23 namespace plugin {
21 namespace { 24 namespace {
22 25
23 template <typename Val> 26 template <typename Val>
24 std::string MakeCommandLineArg(const char* key, const Val val) { 27 std::string MakeCommandLineArg(const char* key, const Val val) {
25 std::stringstream ss; 28 std::stringstream ss;
26 ss << key << val; 29 ss << key << val;
27 return ss.str(); 30 return ss.str();
28 } 31 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 : compiler_subprocess_(NULL), 80 : compiler_subprocess_(NULL),
78 ld_subprocess_(NULL), 81 ld_subprocess_(NULL),
79 compiler_subprocess_active_(false), 82 compiler_subprocess_active_(false),
80 ld_subprocess_active_(false), 83 ld_subprocess_active_(false),
81 done_(false), 84 done_(false),
82 compile_time_(0), 85 compile_time_(0),
83 obj_files_(NULL), 86 obj_files_(NULL),
84 num_threads_(0), 87 num_threads_(0),
85 nexe_file_(NULL), 88 nexe_file_(NULL),
86 coordinator_error_info_(NULL), 89 coordinator_error_info_(NULL),
87 coordinator_(NULL) { 90 coordinator_(NULL),
91 ld_channel_peer_pid_(base::kNullProcessId) {
88 NaClXMutexCtor(&subprocess_mu_); 92 NaClXMutexCtor(&subprocess_mu_);
89 NaClXMutexCtor(&cond_mu_); 93 NaClXMutexCtor(&cond_mu_);
90 NaClXCondVarCtor(&buffer_cond_); 94 NaClXCondVarCtor(&buffer_cond_);
91 } 95 }
92 96
93 void PnaclTranslateThread::SetupState( 97 void PnaclTranslateThread::SetupState(
94 const pp::CompletionCallback& finish_callback, 98 const pp::CompletionCallback& finish_callback,
95 NaClSubprocess* compiler_subprocess, 99 NaClSubprocess* compiler_subprocess,
96 NaClSubprocess* ld_subprocess, 100 NaClSubprocess* ld_subprocess,
97 const std::vector<TempFile*>* obj_files, 101 const std::vector<TempFile*>* obj_files,
(...skipping 19 matching lines...) Expand all
117 report_translate_finished_ = finish_callback; 121 report_translate_finished_ = finish_callback;
118 } 122 }
119 123
120 void PnaclTranslateThread::RunCompile( 124 void PnaclTranslateThread::RunCompile(
121 const pp::CompletionCallback& compile_finished_callback) { 125 const pp::CompletionCallback& compile_finished_callback) {
122 PLUGIN_PRINTF(("PnaclTranslateThread::RunCompile)\n")); 126 PLUGIN_PRINTF(("PnaclTranslateThread::RunCompile)\n"));
123 DCHECK(started()); 127 DCHECK(started());
124 DCHECK(compiler_subprocess_->service_runtime()); 128 DCHECK(compiler_subprocess_->service_runtime());
125 compiler_subprocess_active_ = true; 129 compiler_subprocess_active_ = true;
126 130
131 // Free this IPC channel now to make sure that it does not get freed on
132 // the child thread when the child thread calls Shutdown().
133 // TODO(mseaborn): Convert DoCompile() to using Chrome IPC instead of SRPC,
134 // the same way DoLink() has been converted. Then we will use this IPC
135 // channel instead of just freeing it here.
136 compiler_subprocess_->service_runtime()->TakeTranslatorChannel();
137
127 compile_finished_callback_ = compile_finished_callback; 138 compile_finished_callback_ = compile_finished_callback;
128 translate_thread_.reset(new NaClThread); 139 translate_thread_.reset(new NaClThread);
129 if (translate_thread_ == NULL) { 140 if (translate_thread_ == NULL) {
130 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE, 141 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
131 "could not allocate thread struct."); 142 "could not allocate thread struct.");
132 return; 143 return;
133 } 144 }
134 const int32_t kArbitraryStackSize = 128 * 1024; 145 const int32_t kArbitraryStackSize = 128 * 1024;
135 if (!NaClThreadCreateJoinable(translate_thread_.get(), DoCompileThread, this, 146 if (!NaClThreadCreateJoinable(translate_thread_.get(), DoCompileThread, this,
136 kArbitraryStackSize)) { 147 kArbitraryStackSize)) {
137 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE, 148 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
138 "could not create thread."); 149 "could not create thread.");
139 translate_thread_.reset(NULL); 150 translate_thread_.reset(NULL);
140 } 151 }
141 } 152 }
142 153
143 void PnaclTranslateThread::RunLink() { 154 void PnaclTranslateThread::RunLink() {
144 PLUGIN_PRINTF(("PnaclTranslateThread::RunLink)\n")); 155 PLUGIN_PRINTF(("PnaclTranslateThread::RunLink)\n"));
145 DCHECK(started()); 156 DCHECK(started());
146 DCHECK(ld_subprocess_->service_runtime()); 157 DCHECK(ld_subprocess_->service_runtime());
147 ld_subprocess_active_ = true; 158 ld_subprocess_active_ = true;
148 159
160 // Take ownership of this IPC channel to make sure that it does not get
161 // freed on the child thread when the child thread calls Shutdown().
162 ld_channel_ = ld_subprocess_->service_runtime()->TakeTranslatorChannel();
163 // ld_channel_ is a IPC::SyncChannel, which is not thread-safe and cannot be
164 // used directly by the child thread, so create a SyncMessageFilter which
165 // can be used by the child thread.
166 ld_channel_filter_ = ld_channel_->CreateSyncMessageFilter();
167 // Make a copy of the process ID, again to avoid any thread-safety issues
168 // involved in accessing ld_subprocess_ on the child thread.
169 ld_channel_peer_pid_ = ld_subprocess_->service_runtime()->get_process_id();
170
149 // Tear down the previous thread. 171 // Tear down the previous thread.
150 // TODO(jvoung): Use base/threading or something where we can have a 172 // TODO(jvoung): Use base/threading or something where we can have a
151 // persistent thread and easily post tasks to that persistent thread. 173 // persistent thread and easily post tasks to that persistent thread.
152 NaClThreadJoin(translate_thread_.get()); 174 NaClThreadJoin(translate_thread_.get());
153 translate_thread_.reset(new NaClThread); 175 translate_thread_.reset(new NaClThread);
154 if (translate_thread_ == NULL) { 176 if (translate_thread_ == NULL) {
155 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE, 177 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
156 "could not allocate thread struct."); 178 "could not allocate thread struct.");
157 return; 179 return;
158 } 180 }
(...skipping 18 matching lines...) Expand all
177 NaClXMutexUnlock(&cond_mu_); 199 NaClXMutexUnlock(&cond_mu_);
178 } 200 }
179 201
180 void PnaclTranslateThread::EndStream() { 202 void PnaclTranslateThread::EndStream() {
181 NaClXMutexLock(&cond_mu_); 203 NaClXMutexLock(&cond_mu_);
182 done_ = true; 204 done_ = true;
183 NaClXCondVarSignal(&buffer_cond_); 205 NaClXCondVarSignal(&buffer_cond_);
184 NaClXMutexUnlock(&cond_mu_); 206 NaClXMutexUnlock(&cond_mu_);
185 } 207 }
186 208
209 ppapi::proxy::SerializedHandle PnaclTranslateThread::GetHandleForSubprocess(
210 TempFile* file, int32_t open_flags) {
211 IPC::PlatformFileForTransit file_for_transit;
212
213 #if defined(OS_WIN)
214 if (!content::BrokerDuplicateHandle(
Will Harris 2015/12/22 05:12:08 Is another BrokerAddTargetPeer required here for t
215 file->GetFileHandle(),
216 ld_channel_peer_pid_,
217 &file_for_transit,
218 0, // desired_access is 0 since we're using DUPLICATE_SAME_ACCESS.
219 DUPLICATE_SAME_ACCESS)) {
220 return ppapi::proxy::SerializedHandle();
221 }
222 #else
223 file_for_transit = base::FileDescriptor(dup(file->GetFileHandle()), true);
224 #endif
225
226 // Using 0 disables any use of quota enforcement for this file handle.
227 PP_Resource file_io = 0;
228
229 ppapi::proxy::SerializedHandle handle;
230 handle.set_file_handle(file_for_transit, open_flags, file_io);
231 return handle;
232 }
233
187 void WINAPI PnaclTranslateThread::DoCompileThread(void* arg) { 234 void WINAPI PnaclTranslateThread::DoCompileThread(void* arg) {
188 PnaclTranslateThread* translator = 235 PnaclTranslateThread* translator =
189 reinterpret_cast<PnaclTranslateThread*>(arg); 236 reinterpret_cast<PnaclTranslateThread*>(arg);
190 translator->DoCompile(); 237 translator->DoCompile();
191 } 238 }
192 239
193 void PnaclTranslateThread::DoCompile() { 240 void PnaclTranslateThread::DoCompile() {
194 { 241 {
195 nacl::MutexLocker ml(&subprocess_mu_); 242 nacl::MutexLocker ml(&subprocess_mu_);
196 // If the main thread asked us to exit in between starting the thread 243 // If the main thread asked us to exit in between starting the thread
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 translator->DoLink(); 386 translator->DoLink();
340 } 387 }
341 388
342 void PnaclTranslateThread::DoLink() { 389 void PnaclTranslateThread::DoLink() {
343 { 390 {
344 nacl::MutexLocker ml(&subprocess_mu_); 391 nacl::MutexLocker ml(&subprocess_mu_);
345 // If the main thread asked us to exit in between starting the thread 392 // If the main thread asked us to exit in between starting the thread
346 // and now, just leave now. 393 // and now, just leave now.
347 if (!ld_subprocess_active_) 394 if (!ld_subprocess_active_)
348 return; 395 return;
349 // Now that we are in helper thread, we can do the the blocking 396 }
350 // StartSrpcServices operation. 397
351 if (!ld_subprocess_->StartSrpcServices()) { 398 // Reset object files for reading first. We do this before duplicating
352 TranslateFailed( 399 // handles/FDs to prevent any handle/FD leaks in case any of the Reset()
353 PP_NACL_ERROR_SRPC_CONNECTION_FAIL, 400 // calls fail.
354 "SRPC connection failure for " + ld_subprocess_->description()); 401 for (TempFile* obj_file : *obj_files_) {
402 if (!obj_file->Reset()) {
403 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP,
404 "Link process could not reset object file");
355 return; 405 return;
356 } 406 }
357 } 407 }
358 408
359 SrpcParams params; 409 ppapi::proxy::SerializedHandle nexe_file =
360 std::vector<nacl::DescWrapper*> ld_in_files; 410 GetHandleForSubprocess(nexe_file_, PP_FILEOPENFLAG_WRITE);
361 size_t i; 411 std::vector<ppapi::proxy::SerializedHandle> ld_input_files;
362 for (i = 0; i < obj_files_->size(); i++) { 412 for (TempFile* obj_file : *obj_files_) {
363 // Reset object file for reading first. 413 ld_input_files.push_back(
364 if (!(*obj_files_)[i]->Reset()) { 414 GetHandleForSubprocess(obj_file, PP_FILEOPENFLAG_READ));
365 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP,
366 "Link process could not reset object file");
367 }
368 ld_in_files.push_back((*obj_files_)[i]->read_wrapper());
369 } 415 }
370 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++)
371 ld_in_files.push_back(invalid_desc_wrapper_);
372 416
373 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper();
374 int64_t link_start_time = NaClGetTimeOfDayMicroseconds(); 417 int64_t link_start_time = NaClGetTimeOfDayMicroseconds();
375 // Run LD. 418 bool success = false;
376 bool success = ld_subprocess_->InvokeSrpcMethod( 419 bool sent = ld_channel_filter_->Send(
377 "RunWithSplit", 420 new PpapiMsg_PnaclTranslatorLink(ld_input_files, nexe_file, &success));
378 "ihhhhhhhhhhhhhhhhh", 421 if (!sent) {
379 &params, 422 TranslateFailed(PP_NACL_ERROR_PNACL_LD_INTERNAL,
380 static_cast<int>(obj_files_->size()), 423 "link failed: reply not received from linker.");
381 ld_in_files[0]->desc(), 424 return;
382 ld_in_files[1]->desc(), 425 }
383 ld_in_files[2]->desc(),
384 ld_in_files[3]->desc(),
385 ld_in_files[4]->desc(),
386 ld_in_files[5]->desc(),
387 ld_in_files[6]->desc(),
388 ld_in_files[7]->desc(),
389 ld_in_files[8]->desc(),
390 ld_in_files[9]->desc(),
391 ld_in_files[10]->desc(),
392 ld_in_files[11]->desc(),
393 ld_in_files[12]->desc(),
394 ld_in_files[13]->desc(),
395 ld_in_files[14]->desc(),
396 ld_in_files[15]->desc(),
397 ld_out_file->desc());
398 if (!success) { 426 if (!success) {
399 TranslateFailed(PP_NACL_ERROR_PNACL_LD_INTERNAL, 427 TranslateFailed(PP_NACL_ERROR_PNACL_LD_INTERNAL,
400 "link failed."); 428 "link failed: linker returned failure status.");
401 return; 429 return;
402 } 430 }
431
403 GetNaClInterface()->LogTranslateTime( 432 GetNaClInterface()->LogTranslateTime(
404 "NaCl.Perf.PNaClLoadTime.LinkTime", 433 "NaCl.Perf.PNaClLoadTime.LinkTime",
405 NaClGetTimeOfDayMicroseconds() - link_start_time); 434 NaClGetTimeOfDayMicroseconds() - link_start_time);
406 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n", 435 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n",
407 this)); 436 this));
408 437
409 // Shut down the ld subprocess. 438 // Shut down the ld subprocess.
410 NaClXMutexLock(&subprocess_mu_); 439 NaClXMutexLock(&subprocess_mu_);
411 ld_subprocess_active_ = false; 440 ld_subprocess_active_ = false;
412 ld_subprocess_->Shutdown(); 441 ld_subprocess_->Shutdown();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 AbortSubprocesses(); 488 AbortSubprocesses();
460 if (translate_thread_ != NULL) 489 if (translate_thread_ != NULL)
461 NaClThreadJoin(translate_thread_.get()); 490 NaClThreadJoin(translate_thread_.get());
462 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n")); 491 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n"));
463 NaClCondVarDtor(&buffer_cond_); 492 NaClCondVarDtor(&buffer_cond_);
464 NaClMutexDtor(&cond_mu_); 493 NaClMutexDtor(&cond_mu_);
465 NaClMutexDtor(&subprocess_mu_); 494 NaClMutexDtor(&subprocess_mu_);
466 } 495 }
467 496
468 } // namespace plugin 497 } // namespace plugin
OLDNEW
« no previous file with comments | « components/nacl/renderer/plugin/pnacl_translate_thread.h ('k') | components/nacl/renderer/plugin/service_runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698