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

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

Issue 1128943003: Move PNaCl process startup back to the main thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 7 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 "components/nacl/renderer/plugin/plugin.h" 10 #include "components/nacl/renderer/plugin/plugin.h"
11 #include "components/nacl/renderer/plugin/plugin_error.h" 11 #include "components/nacl/renderer/plugin/plugin_error.h"
12 #include "components/nacl/renderer/plugin/pnacl_resources.h"
13 #include "components/nacl/renderer/plugin/srpc_params.h" 12 #include "components/nacl/renderer/plugin/srpc_params.h"
14 #include "components/nacl/renderer/plugin/temporary_file.h" 13 #include "components/nacl/renderer/plugin/temporary_file.h"
15 #include "components/nacl/renderer/plugin/utility.h" 14 #include "components/nacl/renderer/plugin/utility.h"
16 #include "native_client/src/shared/platform/nacl_check.h" 15 #include "native_client/src/shared/platform/nacl_check.h"
17 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" 16 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
18 #include "ppapi/cpp/var.h" 17 #include "ppapi/cpp/var.h"
19 18
20 namespace plugin { 19 namespace plugin {
21 namespace { 20 namespace {
22 21
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 66
68 for (const std::string& arg : args) { 67 for (const std::string& arg : args) {
69 std::copy(arg.begin(), arg.end(), std::back_inserter(*split_args)); 68 std::copy(arg.begin(), arg.end(), std::back_inserter(*split_args));
70 split_args->push_back('\x00'); 69 split_args->push_back('\x00');
71 } 70 }
72 } 71 }
73 72
74 } // namespace 73 } // namespace
75 74
76 PnaclTranslateThread::PnaclTranslateThread() 75 PnaclTranslateThread::PnaclTranslateThread()
77 : compiler_subprocess_active_(false), 76 : compiler_subprocess_(NULL),
77 ld_subprocess_(NULL),
78 compiler_subprocess_active_(false),
78 ld_subprocess_active_(false), 79 ld_subprocess_active_(false),
79 subprocesses_aborted_(false),
80 done_(false), 80 done_(false),
81 compile_time_(0), 81 compile_time_(0),
82 obj_files_(NULL), 82 obj_files_(NULL),
83 num_threads_(0), 83 num_threads_(0),
84 nexe_file_(NULL), 84 nexe_file_(NULL),
85 coordinator_error_info_(NULL), 85 coordinator_error_info_(NULL),
86 resources_(NULL), 86 coordinator_(NULL) {
87 coordinator_(NULL),
88 plugin_(NULL) {
89 NaClXMutexCtor(&subprocess_mu_); 87 NaClXMutexCtor(&subprocess_mu_);
90 NaClXMutexCtor(&cond_mu_); 88 NaClXMutexCtor(&cond_mu_);
91 NaClXCondVarCtor(&buffer_cond_); 89 NaClXCondVarCtor(&buffer_cond_);
92 } 90 }
93 91
94 void PnaclTranslateThread::RunTranslate( 92 void PnaclTranslateThread::SetupState(
95 const pp::CompletionCallback& finish_callback, 93 const pp::CompletionCallback& finish_callback,
94 NaClSubprocess* compiler_subprocess,
95 NaClSubprocess* ld_subprocess,
96 const std::vector<TempFile*>* obj_files, 96 const std::vector<TempFile*>* obj_files,
97 int num_threads, 97 int num_threads,
98 TempFile* nexe_file, 98 TempFile* nexe_file,
99 nacl::DescWrapper* invalid_desc_wrapper, 99 nacl::DescWrapper* invalid_desc_wrapper,
100 ErrorInfo* error_info, 100 ErrorInfo* error_info,
101 PnaclResources* resources,
102 PP_PNaClOptions* pnacl_options, 101 PP_PNaClOptions* pnacl_options,
103 const std::string& architecture_attributes, 102 const std::string& architecture_attributes,
104 PnaclCoordinator* coordinator, 103 PnaclCoordinator* coordinator) {
105 Plugin* plugin) { 104 PLUGIN_PRINTF(("PnaclTranslateThread::SetupState)\n"));
106 PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n")); 105 compiler_subprocess_ = compiler_subprocess;
106 ld_subprocess_ = ld_subprocess;
107 obj_files_ = obj_files; 107 obj_files_ = obj_files;
108 num_threads_ = num_threads; 108 num_threads_ = num_threads;
109 nexe_file_ = nexe_file; 109 nexe_file_ = nexe_file;
110 invalid_desc_wrapper_ = invalid_desc_wrapper; 110 invalid_desc_wrapper_ = invalid_desc_wrapper;
111 coordinator_error_info_ = error_info; 111 coordinator_error_info_ = error_info;
112 resources_ = resources;
113 pnacl_options_ = pnacl_options; 112 pnacl_options_ = pnacl_options;
114 architecture_attributes_ = architecture_attributes; 113 architecture_attributes_ = architecture_attributes;
115 coordinator_ = coordinator; 114 coordinator_ = coordinator;
116 plugin_ = plugin;
117 115
118 // Invoke llc followed by ld off the main thread. This allows use of
119 // blocking RPCs that would otherwise block the JavaScript main thread.
120 report_translate_finished_ = finish_callback; 116 report_translate_finished_ = finish_callback;
117 }
118
119 void PnaclTranslateThread::RunCompile(
120 const pp::CompletionCallback& compile_finished_callback) {
121 PLUGIN_PRINTF(("PnaclTranslateThread::RunCompile)\n"));
122 DCHECK(started());
123 DCHECK(compiler_subprocess_->service_runtime());
124 compiler_subprocess_active_ = true;
125
126 compile_finished_callback_ = compile_finished_callback;
121 translate_thread_.reset(new NaClThread); 127 translate_thread_.reset(new NaClThread);
122 if (translate_thread_ == NULL) { 128 if (translate_thread_ == NULL) {
123 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE, 129 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
130 "could not allocate thread struct.");
131 return;
132 }
133 const int32_t kArbitraryStackSize = 128 * 1024;
134 if (!NaClThreadCreateJoinable(translate_thread_.get(), DoCompileThread, this,
135 kArbitraryStackSize)) {
136 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
137 "could not create thread.");
138 translate_thread_.reset(NULL);
139 }
140 }
141
142 void PnaclTranslateThread::RunLink() {
143 PLUGIN_PRINTF(("PnaclTranslateThread::RunLink)\n"));
144 DCHECK(started());
145 DCHECK(ld_subprocess_->service_runtime());
146 ld_subprocess_active_ = true;
147
148 // Tear down the previous thread.
149 // TODO(jvoung): Use base/threading or something where we can have a
150 // persistent thread and easily post tasks to that persistent thread.
151 NaClThreadJoin(translate_thread_.get());
152 translate_thread_.reset(new NaClThread);
153 if (translate_thread_ == NULL) {
154 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
124 "could not allocate thread struct."); 155 "could not allocate thread struct.");
125 return; 156 return;
126 } 157 }
127 const int32_t kArbitraryStackSize = 128 * 1024; 158 const int32_t kArbitraryStackSize = 128 * 1024;
128 if (!NaClThreadCreateJoinable(translate_thread_.get(), 159 if (!NaClThreadCreateJoinable(translate_thread_.get(), DoLinkThread, this,
129 DoTranslateThread,
130 this,
131 kArbitraryStackSize)) { 160 kArbitraryStackSize)) {
132 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE, 161 TranslateFailed(PP_NACL_ERROR_PNACL_THREAD_CREATE,
133 "could not create thread."); 162 "could not create thread.");
134 translate_thread_.reset(NULL); 163 translate_thread_.reset(NULL);
135 } 164 }
136 } 165 }
137 166
138 // Called from main thread to send bytes to the translator. 167 // Called from main thread to send bytes to the translator.
139 void PnaclTranslateThread::PutBytes(const void* bytes, int32_t count) { 168 void PnaclTranslateThread::PutBytes(const void* bytes, int32_t count) {
140 CHECK(bytes != NULL); 169 CHECK(bytes != NULL);
141 NaClXMutexLock(&cond_mu_); 170 NaClXMutexLock(&cond_mu_);
142 data_buffers_.push_back(std::vector<char>()); 171 data_buffers_.push_back(std::vector<char>());
143 data_buffers_.back().insert(data_buffers_.back().end(), 172 data_buffers_.back().insert(data_buffers_.back().end(),
144 static_cast<const char*>(bytes), 173 static_cast<const char*>(bytes),
145 static_cast<const char*>(bytes) + count); 174 static_cast<const char*>(bytes) + count);
146 NaClXCondVarSignal(&buffer_cond_); 175 NaClXCondVarSignal(&buffer_cond_);
147 NaClXMutexUnlock(&cond_mu_); 176 NaClXMutexUnlock(&cond_mu_);
148 } 177 }
149 178
150 void PnaclTranslateThread::EndStream() { 179 void PnaclTranslateThread::EndStream() {
151 NaClXMutexLock(&cond_mu_); 180 NaClXMutexLock(&cond_mu_);
152 done_ = true; 181 done_ = true;
153 NaClXCondVarSignal(&buffer_cond_); 182 NaClXCondVarSignal(&buffer_cond_);
154 NaClXMutexUnlock(&cond_mu_); 183 NaClXMutexUnlock(&cond_mu_);
155 } 184 }
156 185
157 void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) { 186 void WINAPI PnaclTranslateThread::DoCompileThread(void* arg) {
158 PnaclTranslateThread* translator = 187 PnaclTranslateThread* translator =
159 reinterpret_cast<PnaclTranslateThread*>(arg); 188 reinterpret_cast<PnaclTranslateThread*>(arg);
160 translator->DoTranslate(); 189 translator->DoCompile();
161 } 190 }
162 191
163 void PnaclTranslateThread::DoTranslate() { 192 void PnaclTranslateThread::DoCompile() {
164 ErrorInfo error_info; 193 // If the main thread asked us to exit in between starting the thread
194 // and now, just leave now.
195 {
196 nacl::MutexLocker ml(&subprocess_mu_);
197 if (!compiler_subprocess_active_)
198 return;
199 }
200
201 // Now that we are in helper thread, we can do the the blocking
202 // StartSrpcServices operation.
203 if (!compiler_subprocess_->StartSrpcServices()) {
204 TranslateFailed(
205 PP_NACL_ERROR_SRPC_CONNECTION_FAIL,
206 "SRPC connection failure for " + compiler_subprocess_->description());
207 return;
208 }
209
165 SrpcParams params; 210 SrpcParams params;
166 std::vector<nacl::DescWrapper*> compile_out_files; 211 std::vector<nacl::DescWrapper*> compile_out_files;
167 size_t i; 212 size_t i;
168 for (i = 0; i < obj_files_->size(); i++) 213 for (i = 0; i < obj_files_->size(); i++)
169 compile_out_files.push_back((*obj_files_)[i]->write_wrapper()); 214 compile_out_files.push_back((*obj_files_)[i]->write_wrapper());
170 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) 215 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++)
171 compile_out_files.push_back(invalid_desc_wrapper_); 216 compile_out_files.push_back(invalid_desc_wrapper_);
172 217
173 PLUGIN_PRINTF( 218 PLUGIN_PRINTF(("DoCompile using subzero: %d\n", pnacl_options_->use_subzero));
174 ("DoTranslate using subzero: %d\n", pnacl_options_->use_subzero));
175 219
176 pp::Core* core = pp::Module::Get()->core(); 220 pp::Core* core = pp::Module::Get()->core();
177 int64_t compiler_load_start_time = NaClGetTimeOfDayMicroseconds();
178 PnaclResources::ResourceType compiler_type = pnacl_options_->use_subzero
179 ? PnaclResources::SUBZERO
180 : PnaclResources::LLC;
181 // Ownership of file_info is transferred here.
182 PP_NaClFileInfo file_info = resources_->TakeFileInfo(compiler_type);
183 const std::string& url = resources_->GetUrl(compiler_type);
184 NaClSubprocess* compiler_subprocess =
185 plugin_->LoadHelperNaClModule(url, file_info, &error_info);
186 if (compiler_subprocess == NULL) {
187 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_SETUP,
188 "Compile process could not be created: " +
189 error_info.message());
190 return;
191 }
192 int64_t compiler_load_time_total =
193 NaClGetTimeOfDayMicroseconds() - compiler_load_start_time;
194 GetNaClInterface()->LogTranslateTime("NaCl.Perf.PNaClLoadTime.LoadCompiler",
195 compiler_load_time_total);
196 GetNaClInterface()->LogTranslateTime(
197 pnacl_options_->use_subzero
198 ? "NaCl.Perf.PNaClLoadTime.LoadCompiler.Subzero"
199 : "NaCl.Perf.PNaClLoadTime.LoadCompiler.LLC",
200 compiler_load_time_total);
201
202 {
203 nacl::MutexLocker ml(&subprocess_mu_);
204 // If we received a call to AbortSubprocesses() before we had a chance to
205 // set compiler_subprocess_, shut down and clean up the subprocess started
206 // here.
207 if (subprocesses_aborted_) {
208 compiler_subprocess->service_runtime()->Shutdown();
209 delete compiler_subprocess;
210 return;
211 }
212 compiler_subprocess_.reset(compiler_subprocess);
213 compiler_subprocess = NULL;
214 compiler_subprocess_active_ = true;
215 }
216
217 int64_t do_compile_start_time = NaClGetTimeOfDayMicroseconds(); 221 int64_t do_compile_start_time = NaClGetTimeOfDayMicroseconds();
218 bool init_success; 222 bool init_success;
219 223
220 std::vector<char> split_args; 224 std::vector<char> split_args;
221 if (pnacl_options_->use_subzero) { 225 if (pnacl_options_->use_subzero) {
222 GetSubzeroCommandLine(&split_args, pnacl_options_->opt_level, 226 GetSubzeroCommandLine(&split_args, pnacl_options_->opt_level,
223 pnacl_options_->is_debug, architecture_attributes_); 227 pnacl_options_->is_debug, architecture_attributes_);
224 } else { 228 } else {
225 GetLlcCommandLine(&split_args, obj_files_->size(), 229 GetLlcCommandLine(&split_args, obj_files_->size(),
226 pnacl_options_->opt_level, pnacl_options_->is_debug, 230 pnacl_options_->opt_level, pnacl_options_->is_debug,
227 architecture_attributes_); 231 architecture_attributes_);
228 } 232 }
233
229 init_success = compiler_subprocess_->InvokeSrpcMethod( 234 init_success = compiler_subprocess_->InvokeSrpcMethod(
230 "StreamInitWithSplit", "ihhhhhhhhhhhhhhhhC", &params, num_threads_, 235 "StreamInitWithSplit", "ihhhhhhhhhhhhhhhhC", &params, num_threads_,
231 compile_out_files[0]->desc(), compile_out_files[1]->desc(), 236 compile_out_files[0]->desc(), compile_out_files[1]->desc(),
232 compile_out_files[2]->desc(), compile_out_files[3]->desc(), 237 compile_out_files[2]->desc(), compile_out_files[3]->desc(),
233 compile_out_files[4]->desc(), compile_out_files[5]->desc(), 238 compile_out_files[4]->desc(), compile_out_files[5]->desc(),
234 compile_out_files[6]->desc(), compile_out_files[7]->desc(), 239 compile_out_files[6]->desc(), compile_out_files[7]->desc(),
235 compile_out_files[8]->desc(), compile_out_files[9]->desc(), 240 compile_out_files[8]->desc(), compile_out_files[9]->desc(),
236 compile_out_files[10]->desc(), compile_out_files[11]->desc(), 241 compile_out_files[10]->desc(), compile_out_files[11]->desc(),
237 compile_out_files[12]->desc(), compile_out_files[13]->desc(), 242 compile_out_files[12]->desc(), compile_out_files[13]->desc(),
238 compile_out_files[14]->desc(), compile_out_files[15]->desc(), 243 compile_out_files[14]->desc(), compile_out_files[15]->desc(),
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 } 315 }
311 compile_time_ = NaClGetTimeOfDayMicroseconds() - do_compile_start_time; 316 compile_time_ = NaClGetTimeOfDayMicroseconds() - do_compile_start_time;
312 GetNaClInterface()->LogTranslateTime("NaCl.Perf.PNaClLoadTime.CompileTime", 317 GetNaClInterface()->LogTranslateTime("NaCl.Perf.PNaClLoadTime.CompileTime",
313 compile_time_); 318 compile_time_);
314 GetNaClInterface()->LogTranslateTime( 319 GetNaClInterface()->LogTranslateTime(
315 pnacl_options_->use_subzero 320 pnacl_options_->use_subzero
316 ? "NaCl.Perf.PNaClLoadTime.CompileTime.Subzero" 321 ? "NaCl.Perf.PNaClLoadTime.CompileTime.Subzero"
317 : "NaCl.Perf.PNaClLoadTime.CompileTime.LLC", 322 : "NaCl.Perf.PNaClLoadTime.CompileTime.LLC",
318 compile_time_); 323 compile_time_);
319 324
320 // Shut down the llc subprocess. 325 // Shut down the compiler subprocess.
321 NaClXMutexLock(&subprocess_mu_); 326 NaClXMutexLock(&subprocess_mu_);
322 compiler_subprocess_active_ = false; 327 compiler_subprocess_active_ = false;
323 compiler_subprocess_.reset(NULL); 328 compiler_subprocess_->Shutdown();
324 NaClXMutexUnlock(&subprocess_mu_); 329 NaClXMutexUnlock(&subprocess_mu_);
325 330
326 if(!RunLdSubprocess()) { 331 core->CallOnMainThread(0, compile_finished_callback_, PP_OK);
332 }
333
334 void WINAPI PnaclTranslateThread::DoLinkThread(void* arg) {
335 PnaclTranslateThread* translator =
336 reinterpret_cast<PnaclTranslateThread*>(arg);
337 translator->DoLink();
338 }
339
340 void PnaclTranslateThread::DoLink() {
341 // If the main thread asked us to exit in between starting the thread
342 // and now, just leave now.
343 {
344 nacl::MutexLocker ml(&subprocess_mu_);
345 if (!ld_subprocess_active_)
346 return;
347 }
348
349 // Now that we are in helper thread, we can do the the blocking
350 // StartSrpcServices operation.
351 if (!ld_subprocess_->StartSrpcServices()) {
352 TranslateFailed(
353 PP_NACL_ERROR_SRPC_CONNECTION_FAIL,
354 "SRPC connection failure for " + ld_subprocess_->description());
327 return; 355 return;
328 } 356 }
329 core->CallOnMainThread(0, report_translate_finished_, PP_OK);
330 }
331 357
332 bool PnaclTranslateThread::RunLdSubprocess() {
333 ErrorInfo error_info;
334 SrpcParams params; 358 SrpcParams params;
335
336 std::vector<nacl::DescWrapper*> ld_in_files; 359 std::vector<nacl::DescWrapper*> ld_in_files;
337 size_t i; 360 size_t i;
338 for (i = 0; i < obj_files_->size(); i++) { 361 for (i = 0; i < obj_files_->size(); i++) {
339 // Reset object file for reading first. 362 // Reset object file for reading first.
340 if (!(*obj_files_)[i]->Reset()) { 363 if (!(*obj_files_)[i]->Reset()) {
341 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP, 364 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP,
342 "Link process could not reset object file"); 365 "Link process could not reset object file");
343 return false;
344 } 366 }
345 ld_in_files.push_back((*obj_files_)[i]->read_wrapper()); 367 ld_in_files.push_back((*obj_files_)[i]->read_wrapper());
346 } 368 }
347 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) 369 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++)
348 ld_in_files.push_back(invalid_desc_wrapper_); 370 ld_in_files.push_back(invalid_desc_wrapper_);
349 371
350 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper(); 372 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper();
351 int64_t ld_start_time = NaClGetTimeOfDayMicroseconds();
352 PP_NaClFileInfo ld_file_info = resources_->TakeFileInfo(PnaclResources::LD);
353 // Ownership of ld_file_info is transferred here.
354 nacl::scoped_ptr<NaClSubprocess> ld_subprocess(plugin_->LoadHelperNaClModule(
355 resources_->GetUrl(PnaclResources::LD), ld_file_info, &error_info));
356 if (ld_subprocess.get() == NULL) {
357 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP,
358 "Link process could not be created: " +
359 error_info.message());
360 return false;
361 }
362 GetNaClInterface()->LogTranslateTime(
363 "NaCl.Perf.PNaClLoadTime.LoadLinker",
364 NaClGetTimeOfDayMicroseconds() - ld_start_time);
365 {
366 nacl::MutexLocker ml(&subprocess_mu_);
367 // If we received a call to AbortSubprocesses() before we had a chance to
368 // set ld_subprocess_, shut down and clean up the subprocess started here.
369 if (subprocesses_aborted_) {
370 ld_subprocess->service_runtime()->Shutdown();
371 return false;
372 }
373 DCHECK(ld_subprocess_.get() == NULL);
374 ld_subprocess_.swap(ld_subprocess);
375 ld_subprocess_active_ = true;
376 }
377
378 int64_t link_start_time = NaClGetTimeOfDayMicroseconds(); 373 int64_t link_start_time = NaClGetTimeOfDayMicroseconds();
379 // Run LD. 374 // Run LD.
380 bool success = ld_subprocess_->InvokeSrpcMethod( 375 bool success = ld_subprocess_->InvokeSrpcMethod(
381 "RunWithSplit", 376 "RunWithSplit",
382 "ihhhhhhhhhhhhhhhhh", 377 "ihhhhhhhhhhhhhhhhh",
383 &params, 378 &params,
384 static_cast<int>(obj_files_->size()), 379 static_cast<int>(obj_files_->size()),
385 ld_in_files[0]->desc(), 380 ld_in_files[0]->desc(),
386 ld_in_files[1]->desc(), 381 ld_in_files[1]->desc(),
387 ld_in_files[2]->desc(), 382 ld_in_files[2]->desc(),
388 ld_in_files[3]->desc(), 383 ld_in_files[3]->desc(),
389 ld_in_files[4]->desc(), 384 ld_in_files[4]->desc(),
390 ld_in_files[5]->desc(), 385 ld_in_files[5]->desc(),
391 ld_in_files[6]->desc(), 386 ld_in_files[6]->desc(),
392 ld_in_files[7]->desc(), 387 ld_in_files[7]->desc(),
393 ld_in_files[8]->desc(), 388 ld_in_files[8]->desc(),
394 ld_in_files[9]->desc(), 389 ld_in_files[9]->desc(),
395 ld_in_files[10]->desc(), 390 ld_in_files[10]->desc(),
396 ld_in_files[11]->desc(), 391 ld_in_files[11]->desc(),
397 ld_in_files[12]->desc(), 392 ld_in_files[12]->desc(),
398 ld_in_files[13]->desc(), 393 ld_in_files[13]->desc(),
399 ld_in_files[14]->desc(), 394 ld_in_files[14]->desc(),
400 ld_in_files[15]->desc(), 395 ld_in_files[15]->desc(),
401 ld_out_file->desc()); 396 ld_out_file->desc());
402 if (!success) { 397 if (!success) {
403 TranslateFailed(PP_NACL_ERROR_PNACL_LD_INTERNAL, 398 TranslateFailed(PP_NACL_ERROR_PNACL_LD_INTERNAL,
404 "link failed."); 399 "link failed.");
405 return false; 400 return;
406 } 401 }
407 GetNaClInterface()->LogTranslateTime( 402 GetNaClInterface()->LogTranslateTime(
408 "NaCl.Perf.PNaClLoadTime.LinkTime", 403 "NaCl.Perf.PNaClLoadTime.LinkTime",
409 NaClGetTimeOfDayMicroseconds() - link_start_time); 404 NaClGetTimeOfDayMicroseconds() - link_start_time);
410 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n", 405 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n",
411 this)); 406 this));
407
412 // Shut down the ld subprocess. 408 // Shut down the ld subprocess.
413 NaClXMutexLock(&subprocess_mu_); 409 NaClXMutexLock(&subprocess_mu_);
414 ld_subprocess_active_ = false; 410 ld_subprocess_active_ = false;
415 ld_subprocess_.reset(NULL); 411 ld_subprocess_->Shutdown();
416 NaClXMutexUnlock(&subprocess_mu_); 412 NaClXMutexUnlock(&subprocess_mu_);
417 return true; 413
414 pp::Core* core = pp::Module::Get()->core();
415 core->CallOnMainThread(0, report_translate_finished_, PP_OK);
418 } 416 }
419 417
420 void PnaclTranslateThread::TranslateFailed( 418 void PnaclTranslateThread::TranslateFailed(
421 PP_NaClError err_code, 419 PP_NaClError err_code,
422 const std::string& error_string) { 420 const std::string& error_string) {
423 PLUGIN_PRINTF(("PnaclTranslateThread::TranslateFailed (error_string='%s')\n", 421 PLUGIN_PRINTF(("PnaclTranslateThread::TranslateFailed (error_string='%s')\n",
424 error_string.c_str())); 422 error_string.c_str()));
425 pp::Core* core = pp::Module::Get()->core(); 423 pp::Core* core = pp::Module::Get()->core();
426 if (coordinator_error_info_->message().empty()) { 424 if (coordinator_error_info_->message().empty()) {
427 // Only use our message if one hasn't already been set by the coordinator 425 // Only use our message if one hasn't already been set by the coordinator
428 // (e.g. pexe load failed). 426 // (e.g. pexe load failed).
429 coordinator_error_info_->SetReport(err_code, 427 coordinator_error_info_->SetReport(err_code,
430 std::string("PnaclCoordinator: ") + 428 std::string("PnaclCoordinator: ") +
431 error_string); 429 error_string);
432 } 430 }
433 core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED); 431 core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED);
434 } 432 }
435 433
436 void PnaclTranslateThread::AbortSubprocesses() { 434 void PnaclTranslateThread::AbortSubprocesses() {
437 PLUGIN_PRINTF(("PnaclTranslateThread::AbortSubprocesses\n")); 435 PLUGIN_PRINTF(("PnaclTranslateThread::AbortSubprocesses\n"));
438 NaClXMutexLock(&subprocess_mu_); 436 NaClXMutexLock(&subprocess_mu_);
439 if (compiler_subprocess_ != NULL && compiler_subprocess_active_) { 437 if (compiler_subprocess_ != NULL && compiler_subprocess_active_) {
438 // We only run the service_runtime's Shutdown and do not run the
439 // NaClSubprocess Shutdown, which would otherwise nullify some
440 // pointers that could still be in use (srpc_client, etc.).
440 compiler_subprocess_->service_runtime()->Shutdown(); 441 compiler_subprocess_->service_runtime()->Shutdown();
441 compiler_subprocess_active_ = false; 442 compiler_subprocess_active_ = false;
442 } 443 }
443 if (ld_subprocess_ != NULL && ld_subprocess_active_) { 444 if (ld_subprocess_ != NULL && ld_subprocess_active_) {
444 ld_subprocess_->service_runtime()->Shutdown(); 445 ld_subprocess_->service_runtime()->Shutdown();
445 ld_subprocess_active_ = false; 446 ld_subprocess_active_ = false;
446 } 447 }
447 subprocesses_aborted_ = true;
448 NaClXMutexUnlock(&subprocess_mu_); 448 NaClXMutexUnlock(&subprocess_mu_);
449 nacl::MutexLocker ml(&cond_mu_); 449 nacl::MutexLocker ml(&cond_mu_);
450 done_ = true; 450 done_ = true;
451 // Free all buffered bitcode chunks 451 // Free all buffered bitcode chunks
452 data_buffers_.clear(); 452 data_buffers_.clear();
453 NaClXCondVarSignal(&buffer_cond_); 453 NaClXCondVarSignal(&buffer_cond_);
454 } 454 }
455 455
456 PnaclTranslateThread::~PnaclTranslateThread() { 456 PnaclTranslateThread::~PnaclTranslateThread() {
457 PLUGIN_PRINTF(("~PnaclTranslateThread (translate_thread=%p)\n", this)); 457 PLUGIN_PRINTF(("~PnaclTranslateThread (translate_thread=%p)\n", this));
458 AbortSubprocesses(); 458 AbortSubprocesses();
459 if (translate_thread_ != NULL) 459 if (translate_thread_ != NULL)
460 NaClThreadJoin(translate_thread_.get()); 460 NaClThreadJoin(translate_thread_.get());
461 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n")); 461 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n"));
462 NaClCondVarDtor(&buffer_cond_); 462 NaClCondVarDtor(&buffer_cond_);
463 NaClMutexDtor(&cond_mu_); 463 NaClMutexDtor(&cond_mu_);
464 NaClMutexDtor(&subprocess_mu_); 464 NaClMutexDtor(&subprocess_mu_);
465 } 465 }
466 466
467 } // namespace plugin 467 } // 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