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

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

Issue 10827109: Simplify Pnacl translation thread code (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
(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_streaming_translate_thread.h"
6
7 #include "native_client/src/include/nacl_scoped_ptr.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/temporary_file.h"
12
13 namespace plugin {
14
15 PnaclStreamingTranslateThread::PnaclStreamingTranslateThread() : done_(false) {
16 NaClXMutexCtor(&cond_mu_);
17 NaClXCondVarCtor(&buffer_cond_);
18 }
19
20 PnaclStreamingTranslateThread::~PnaclStreamingTranslateThread() {
21 PLUGIN_PRINTF(("~PnaclTranslateThread (translate_thread=%p)\n", this));
22 SetSubprocessesShouldDie();
23 NaClThreadJoin(translate_thread_.get());
24 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n"));
25 }
26
27 void PnaclStreamingTranslateThread::RunTranslate(
28 const pp::CompletionCallback& finish_callback,
29 const Manifest* manifest,
30 const Manifest* ld_manifest,
31 TempFile* obj_file,
32 LocalTempFile* nexe_file,
33 ErrorInfo* error_info,
34 PnaclResources* resources,
35 Plugin* plugin) {
36 PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n"));
37 manifest_ = manifest;
38 ld_manifest_ = ld_manifest;
39 obj_file_ = obj_file;
40 nexe_file_ = nexe_file;
41 coordinator_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.");
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 translate_thread_.reset(NULL);
60 }
61 }
62
63 // Called from main thread to send bytes to the translator.
64 void PnaclStreamingTranslateThread::PutBytes(std::vector<char>* bytes,
65 int count) {
66 PLUGIN_PRINTF(("PutBytes, this %p bytes %p, size %d, count %d\n", this, bytes,
67 bytes ? bytes->size(): 0, count));
68 size_t buffer_size = 0;
69 // If we are done (error or not), Signal the translation thread to stop.
70 if (count <= PP_OK) {
71 NaClXMutexLock(&cond_mu_);
72 done_ = true;
73 NaClXCondVarSignal(&buffer_cond_);
74 NaClXMutexUnlock(&cond_mu_);
75 return;
76 }
77
78 CHECK(bytes != NULL);
79 // Ensure that the buffer we send to the translation thread is the right size
80 // (count can be < the buffer size). This can be done without the lock.
81 buffer_size = bytes->size();
82 bytes->resize(count);
83
84 NaClXMutexLock(&cond_mu_);
85
86 data_buffers_.push_back(std::vector<char>());
87 bytes->swap(data_buffers_.back()); // Avoid copying the buffer data.
88
89 NaClXCondVarSignal(&buffer_cond_);
90 NaClXMutexUnlock(&cond_mu_);
91
92 // Ensure the buffer we send back to the coordinator is the expected size
93 bytes->resize(buffer_size);
94 }
95
96 void PnaclStreamingTranslateThread::DoTranslate() {
97 ErrorInfo error_info;
98 nacl::scoped_ptr<NaClSubprocess> llc_subprocess(
99 StartSubprocess(PnaclUrls::GetLlcUrl(), manifest_, &error_info));
100 if (llc_subprocess == NULL) {
101 TranslateFailed("Compile process could not be created: " +
102 error_info.message());
103 return;
104 }
105 // Run LLC.
106 SrpcParams params;
107 nacl::DescWrapper* llc_out_file = obj_file_->get_wrapper();
108 PluginReverseInterface* llc_reverse =
109 llc_subprocess->service_runtime()->rev_interface();
110 llc_reverse->AddTempQuotaManagedFile(obj_file_->identifier());
111 RegisterReverseInterface(llc_reverse);
112
113 if (!llc_subprocess->InvokeSrpcMethod("StreamInit",
114 "h",
115 &params,
116 llc_out_file->desc())) {
117 // StreamInit returns an error message if the RPC fails.
118 TranslateFailed(nacl::string("Stream init failed: ") +
119 nacl::string(params.outs()[0]->arrays.str));
120 return;
121 }
122
123 PLUGIN_PRINTF(("PnaclCoordinator: StreamInit successful\n"));
124
125 // llc process is started.
126 while(!done_ || data_buffers_.size() > 0) {
127 NaClXMutexLock(&cond_mu_);
128 while(!done_ && data_buffers_.size() == 0) {
129 NaClXCondVarWait(&buffer_cond_, &cond_mu_);
130 }
131 PLUGIN_PRINTF(("PnaclTranslateThread awake, done %d, size %d\n",
132 done_, data_buffers_.size()));
133 if (data_buffers_.size() > 0) {
134 std::vector<char> data;
135 data.swap(data_buffers_.front());
136 data_buffers_.pop_front();
137 NaClXMutexUnlock(&cond_mu_);
138 PLUGIN_PRINTF(("StreamChunk\n"));
139 if (!llc_subprocess->InvokeSrpcMethod("StreamChunk",
140 "C",
141 &params,
142 &data[0],
143 data.size())) {
144 TranslateFailed("Compile stream chunk failed.");
145 return;
146 }
147 PLUGIN_PRINTF(("StreamChunk Successful\n"));
148 } else {
149 NaClXMutexUnlock(&cond_mu_);
150 }
151 if (SubprocessesShouldDie()) {
152 TranslateFailed("Stopped by coordinator.");
153 return;
154 }
155 }
156 PLUGIN_PRINTF(("PnaclTranslateThread done with chunks\n"));
157 // Finish llc.
158 if(!llc_subprocess->InvokeSrpcMethod("StreamEnd",
159 "",
160 &params)) {
161 PLUGIN_PRINTF(("PnaclTranslateThread StreamEnd failed\n"));
162 TranslateFailed(params.outs()[3]->arrays.str);
163 return;
164 }
165 // LLC returns values that are used to determine how linking is done.
166 int is_shared_library = (params.outs()[0]->u.ival != 0);
167 nacl::string soname = params.outs()[1]->arrays.str;
168 nacl::string lib_dependencies = params.outs()[2]->arrays.str;
169 PLUGIN_PRINTF(("PnaclCoordinator: compile (translator=%p) succeeded"
170 " is_shared_library=%d, soname='%s', lib_dependencies='%s')\n",
171 this, is_shared_library, soname.c_str(),
172 lib_dependencies.c_str()));
173
174 // Shut down the llc subprocess.
175 RegisterReverseInterface(NULL);
176 llc_subprocess.reset(NULL);
177 if (SubprocessesShouldDie()) {
178 TranslateFailed("stopped by coordinator.");
179 return;
180 }
181
182 if(!RunLdSubprocess(is_shared_library, soname, lib_dependencies)) {
183 return;
184 }
185 pp::Core* core = pp::Module::Get()->core();
186 core->CallOnMainThread(0, report_translate_finished_, PP_OK);
187 }
188
189 void PnaclStreamingTranslateThread::SetSubprocessesShouldDie() {
190 PnaclTranslateThread::SetSubprocessesShouldDie();
191 nacl::MutexLocker ml(&cond_mu_);
192 done_ = true;
193 NaClXCondVarSignal(&buffer_cond_);
194 }
195
196 } // namespace plugin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698