OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "native_client/src/trusted/plugin/pnacl_translate_thread.h" | |
6 | |
7 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | |
8 #include "native_client/src/trusted/plugin/plugin.h" | |
9 #include "native_client/src/trusted/plugin/pnacl_resources.h" | |
10 #include "native_client/src/trusted/plugin/srpc_params.h" | |
11 #include "native_client/src/trusted/plugin/utility.h" | |
12 | |
13 namespace plugin { | |
14 | |
15 PnaclTranslateThread::PnaclTranslateThread() : subprocesses_should_die_(false), | |
16 manifest_(NULL), | |
17 obj_file_(NULL), | |
18 nexe_file_(NULL), | |
19 pexe_wrapper_(NULL), | |
20 error_info_(NULL), | |
21 resources_(NULL), | |
22 plugin_(NULL) { | |
23 NaClXMutexCtor(&subprocess_mu_); | |
24 } | |
25 | |
26 void PnaclTranslateThread::RunTranslate(pp::CompletionCallback finish_callback, | |
27 const Manifest* manifest, | |
28 const Manifest* ld_manifest, | |
29 LocalTempFile* obj_file, | |
30 LocalTempFile* nexe_file, | |
31 nacl::DescWrapper* pexe_wrapper, | |
32 ErrorInfo* error_info, | |
33 PnaclResources* resources, | |
34 Plugin* plugin) { | |
35 PLUGIN_PRINTF(("PnaclTranslateThread::RunTranslate)\n")); | |
36 manifest_ = manifest; | |
37 ld_manifest_ = ld_manifest; | |
38 obj_file_ = obj_file; | |
39 nexe_file_ = nexe_file; | |
40 pexe_wrapper_ = pexe_wrapper; | |
41 error_info_ = error_info; | |
42 resources_ = resources; | |
43 plugin_ = plugin; | |
44 | |
45 // Invoke llc followed by ld off the main thread. This allows use of | |
46 // blocking RPCs that would otherwise block the JavaScript main thread. | |
47 report_translate_finished_ = finish_callback; | |
48 translate_thread_.reset(new NaClThread); | |
49 if (translate_thread_ == NULL) { | |
50 TranslateFailed("could not allocate thread struct."); | |
Derek Schuff
2012/05/15 23:17:20
This (and line 58) is now TranslateFailed callback
| |
51 return; | |
52 } | |
53 const int32_t kArbitraryStackSize = 128 * 1024; | |
54 if (!NaClThreadCreateJoinable(translate_thread_.get(), | |
55 DoTranslateThread, | |
56 this, | |
57 kArbitraryStackSize)) { | |
58 TranslateFailed("could not create thread."); | |
59 } | |
60 } | |
61 | |
62 NaClSubprocess* PnaclTranslateThread::StartSubprocess( | |
63 const nacl::string& url_for_nexe, | |
64 const Manifest* manifest) { | |
65 PLUGIN_PRINTF(("PnaclTranslateThread::StartSubprocess (url_for_nexe=%s)\n", | |
66 url_for_nexe.c_str())); | |
67 nacl::DescWrapper* wrapper = resources_->WrapperForUrl(url_for_nexe); | |
68 nacl::scoped_ptr<NaClSubprocess> subprocess( | |
69 plugin_->LoadHelperNaClModule(wrapper, manifest, error_info_)); | |
70 if (subprocess.get() == NULL) { | |
71 PLUGIN_PRINTF(( | |
72 "PnaclTranslateThread::StartSubprocess: subprocess creation failed\n")); | |
73 return NULL; | |
74 } | |
75 return subprocess.release(); | |
76 } | |
77 | |
78 void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) { | |
79 PnaclTranslateThread* translator = | |
80 reinterpret_cast<PnaclTranslateThread*>(arg); | |
81 nacl::scoped_ptr<NaClSubprocess> llc_subprocess( | |
82 translator->StartSubprocess(PnaclUrls::GetLlcUrl(), | |
83 translator->manifest_)); | |
84 if (llc_subprocess == NULL) { | |
85 translator->TranslateFailed("Compile process could not be created."); | |
86 return; | |
87 } | |
88 // Run LLC. | |
89 SrpcParams params; | |
90 nacl::DescWrapper* llc_out_file = translator->obj_file_->write_wrapper(); | |
91 PluginReverseInterface* llc_reverse = | |
92 llc_subprocess->service_runtime()->rev_interface(); | |
93 llc_reverse->AddQuotaManagedFile(translator->obj_file_->identifier(), | |
94 translator->obj_file_->write_file_io()); | |
95 if (!llc_subprocess->InvokeSrpcMethod("RunWithDefaultCommandLine", | |
96 "hh", | |
97 ¶ms, | |
98 translator->pexe_wrapper_->desc(), | |
99 llc_out_file->desc())) { | |
100 translator->TranslateFailed("compile failed."); | |
101 return; | |
102 } | |
103 // LLC returns values that are used to determine how linking is done. | |
104 int is_shared_library = (params.outs()[0]->u.ival != 0); | |
105 nacl::string soname = params.outs()[1]->arrays.str; | |
106 nacl::string lib_dependencies = params.outs()[2]->arrays.str; | |
107 PLUGIN_PRINTF(("PnaclCoordinator: compile (translator=%p) succeeded" | |
108 " is_shared_library=%d, soname='%s', lib_dependencies='%s')\n", | |
109 arg, is_shared_library, soname.c_str(), | |
110 lib_dependencies.c_str())); | |
111 // Shut down the llc subprocess. | |
112 llc_subprocess.reset(NULL); | |
113 if (translator->SubprocessesShouldDie()) { | |
114 translator->TranslateFailed("stopped by coordinator."); | |
115 return; | |
116 } | |
117 nacl::scoped_ptr<NaClSubprocess> ld_subprocess( | |
118 translator->StartSubprocess(PnaclUrls::GetLdUrl(), | |
119 translator->ld_manifest_)); | |
120 if (ld_subprocess == NULL) { | |
121 translator->TranslateFailed("Link process could not be created."); | |
122 return; | |
123 } | |
124 // Run LD. | |
125 nacl::DescWrapper* ld_in_file = translator->obj_file_->read_wrapper(); | |
126 nacl::DescWrapper* ld_out_file = translator->nexe_file_->write_wrapper(); | |
127 PluginReverseInterface* ld_reverse = | |
128 ld_subprocess->service_runtime()->rev_interface(); | |
129 ld_reverse->AddQuotaManagedFile(translator->nexe_file_->identifier(), | |
130 translator->nexe_file_->write_file_io()); | |
131 if (!ld_subprocess->InvokeSrpcMethod("RunWithDefaultCommandLine", | |
132 "hhiCC", | |
133 ¶ms, | |
134 ld_in_file->desc(), | |
135 ld_out_file->desc(), | |
136 is_shared_library, | |
137 soname.c_str(), | |
138 lib_dependencies.c_str())) { | |
139 translator->TranslateFailed("link failed."); | |
140 return; | |
141 } | |
142 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n", arg)); | |
143 // Shut down the ld subprocess. | |
144 ld_subprocess.reset(NULL); | |
145 if (translator->SubprocessesShouldDie()) { | |
146 translator->TranslateFailed("stopped by coordinator."); | |
147 return; | |
148 } | |
149 pp::Core* core = pp::Module::Get()->core(); | |
150 core->CallOnMainThread(0, translator->report_translate_finished_, PP_OK); | |
151 } | |
152 | |
153 void PnaclTranslateThread::TranslateFailed(const nacl::string& error_string) { | |
154 PLUGIN_PRINTF(("PnaclTranslateThread::TranslateFailed (error_string='%s')\n", | |
155 error_string.c_str())); | |
156 pp::Core* core = pp::Module::Get()->core(); | |
157 error_info_->SetReport(ERROR_UNKNOWN, | |
158 nacl::string("PnaclCoordinator: ") + error_string); | |
159 core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED); | |
160 } | |
161 | |
162 bool PnaclTranslateThread::SubprocessesShouldDie() { | |
163 nacl::MutexLocker ml(&subprocess_mu_); | |
164 return subprocesses_should_die_; | |
165 } | |
166 | |
167 void PnaclTranslateThread::SetSubprocessesShouldDie( | |
168 bool subprocesses_should_die) { | |
169 nacl::MutexLocker ml(&subprocess_mu_); | |
170 subprocesses_should_die_ = subprocesses_should_die; | |
171 } | |
172 | |
173 PnaclTranslateThread::~PnaclTranslateThread() { | |
174 NaClMutexDtor(&subprocess_mu_); | |
175 } | |
176 | |
177 } // namespace plugin | |
OLD | NEW |