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

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