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 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ | |
6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ | |
7 | |
8 #include <vector> | |
9 | |
10 #include "native_client/src/include/nacl_macros.h" | |
11 #include "native_client/src/shared/platform/nacl_sync_raii.h" | |
12 #include "native_client/src/shared/srpc/nacl_srpc.h" | |
13 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | |
14 | |
15 #include "ppapi/cpp/completion_callback.h" | |
16 | |
17 #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h" | |
18 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" | |
19 #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h" | |
20 | |
21 #include "ppapi/utility/completion_callback_factory.h" | |
22 | |
23 struct PP_PNaClOptions; | |
24 | |
25 namespace plugin { | |
26 | |
27 class Plugin; | |
28 class PnaclCoordinator; | |
29 class PnaclTranslateThread; | |
30 class TempFile; | |
31 | |
32 // A class invoked by Plugin to handle PNaCl client-side translation. | |
33 // Usage: | |
34 // (1) Invoke the factory method, e.g., | |
35 // PnaclCoordinator* coord = BitcodeToNative(plugin, | |
36 // "http://foo.com/my.pexe", | |
37 // pnacl_options, | |
38 // TranslateNotifyCallback); | |
39 // (2) TranslateNotifyCallback gets invoked when translation is complete. | |
40 // If the translation was successful, the pp_error argument is PP_OK. | |
41 // Other values indicate errors. | |
42 // (3) After finish_callback runs, get the file descriptor of the translated | |
43 // nexe, e.g., | |
44 // fd = coord->ReleaseTranslatedFD(); | |
45 // (4) Load the nexe from "fd". | |
46 // (5) delete coord. | |
47 // | |
48 // Translation proceeds in two steps: | |
49 // (1) llc translates the bitcode in pexe_url_ to an object in obj_file_. | |
50 // (2) ld links the object code in obj_file_ and produces a nexe in nexe_file_. | |
51 class PnaclCoordinator { | |
52 public: | |
53 // Maximum number of object files passable to the translator. Cannot be | |
54 // changed without changing the RPC signatures. | |
55 const static size_t kMaxTranslatorObjectFiles = 16; | |
56 virtual ~PnaclCoordinator(); | |
57 | |
58 // The factory method for translations. | |
59 static PnaclCoordinator* BitcodeToNative( | |
60 Plugin* plugin, | |
61 const std::string& pexe_url, | |
62 const PP_PNaClOptions& pnacl_options, | |
63 const pp::CompletionCallback& translate_notify_callback); | |
64 | |
65 // Call this to take ownership of the FD of the translated nexe after | |
66 // BitcodeToNative has completed (and the finish_callback called). | |
67 PP_FileHandle TakeTranslatedFileHandle(); | |
68 | |
69 // Return a callback that should be notified when |bytes_compiled| bytes | |
70 // have been compiled. | |
71 pp::CompletionCallback GetCompileProgressCallback(int64_t bytes_compiled); | |
72 | |
73 // Return true if we should delay the progress event reporting. | |
74 // This delay approximates: | |
75 // - the size of the buffer of bytes sent but not-yet-compiled by LLC. | |
76 // - the linking time. | |
77 bool ShouldDelayProgressEvent() { | |
78 const uint32_t kProgressEventSlopPct = 5; | |
79 return ((expected_pexe_size_ - pexe_bytes_compiled_) * 100 / | |
80 expected_pexe_size_) < kProgressEventSlopPct; | |
81 } | |
82 | |
83 | |
84 void BitcodeStreamCacheHit(PP_FileHandle handle); | |
85 void BitcodeStreamCacheMiss(int64_t expected_pexe_size, | |
86 PP_FileHandle handle); | |
87 | |
88 // Invoked when a pexe data chunk arrives (when using streaming translation) | |
89 void BitcodeStreamGotData(const void* data, int32_t length); | |
90 | |
91 // Invoked when the pexe download finishes (using streaming translation) | |
92 void BitcodeStreamDidFinish(int32_t pp_error); | |
93 | |
94 private: | |
95 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator); | |
96 | |
97 // BitcodeToNative is the factory method for PnaclCoordinators. | |
98 // Therefore the constructor is private. | |
99 PnaclCoordinator(Plugin* plugin, | |
100 const std::string& pexe_url, | |
101 const PP_PNaClOptions& pnacl_options, | |
102 const pp::CompletionCallback& translate_notify_callback); | |
103 | |
104 // Invoke to issue a GET request for bitcode. | |
105 void OpenBitcodeStream(); | |
106 | |
107 // Invoked when a pexe data chunk is compiled. | |
108 void BitcodeGotCompiled(int32_t pp_error, int64_t bytes_compiled); | |
109 // Once llc and ld nexes have been loaded and the two temporary files have | |
110 // been created, this starts the translation. Translation starts two | |
111 // subprocesses, one for llc and one for ld. | |
112 void RunTranslate(int32_t pp_error); | |
113 | |
114 // Invoked when translation is finished. | |
115 void TranslateFinished(int32_t pp_error); | |
116 | |
117 // Invoked when the read descriptor for nexe_file_ is created. | |
118 void NexeReadDidOpen(int32_t pp_error); | |
119 | |
120 // Bring control back to the plugin by invoking the | |
121 // |translate_notify_callback_|. This does not set the ErrorInfo report, | |
122 // it is assumed that it was already set. | |
123 void ExitWithError(); | |
124 // Run |translate_notify_callback_| with an error condition that is not | |
125 // PPAPI specific. Also set ErrorInfo report. | |
126 void ReportNonPpapiError(PP_NaClError err, const std::string& message); | |
127 // Run when faced with a PPAPI error condition. Bring control back to the | |
128 // plugin by invoking the |translate_notify_callback_|. | |
129 // Also set ErrorInfo report. | |
130 void ReportPpapiError(PP_NaClError err, | |
131 int32_t pp_error, const std::string& message); | |
132 | |
133 | |
134 // Keeps track of the pp_error upon entry to TranslateFinished, | |
135 // for inspection after cleanup. | |
136 int32_t translate_finish_error_; | |
137 | |
138 // The plugin owning the nexe for which we are doing translation. | |
139 Plugin* plugin_; | |
140 | |
141 pp::CompletionCallback translate_notify_callback_; | |
142 // Set to true when the translation (if applicable) is finished and the nexe | |
143 // file is loaded, (or when there was an error), and the browser has been | |
144 // notified via ReportTranslationFinished. If it is not set before | |
145 // plugin/coordinator destruction, the destructor will call | |
146 // ReportTranslationFinished. | |
147 bool translation_finished_reported_; | |
148 // Threadsafety is required to support file lookups. | |
149 pp::CompletionCallbackFactory<PnaclCoordinator, | |
150 pp::ThreadSafeThreadTraits> callback_factory_; | |
151 | |
152 // An auxiliary class that manages downloaded resources (llc and ld nexes). | |
153 nacl::scoped_ptr<PnaclResources> resources_; | |
154 | |
155 // The URL for the pexe file. | |
156 std::string pexe_url_; | |
157 // Options for translation. | |
158 PP_PNaClOptions pnacl_options_; | |
159 // Architecture-specific attributes used for translation. These are | |
160 // supplied by Chrome, not the developer, and are therefore different | |
161 // from PNaCl options. | |
162 std::string architecture_attributes_; | |
163 | |
164 // Object file, produced by the translator and consumed by the linker. | |
165 std::vector<TempFile*> obj_files_; | |
166 nacl::scoped_ptr<nacl::DescWrapper> invalid_desc_wrapper_; | |
167 // Number of split modules (threads) for llc | |
168 int split_module_count_; | |
169 | |
170 // Translated nexe file, produced by the linker. | |
171 nacl::scoped_ptr<TempFile> temp_nexe_file_; | |
172 | |
173 // Used to report information when errors (PPAPI or otherwise) are reported. | |
174 ErrorInfo error_info_; | |
175 | |
176 // True if an error was already reported, and translate_notify_callback_ | |
177 // was already run/consumed. | |
178 bool error_already_reported_; | |
179 | |
180 // State for timing and size information for UMA stats. | |
181 int64_t pexe_size_; // Count as we stream -- will converge to pexe size. | |
182 int64_t pexe_bytes_compiled_; // Count as we compile. | |
183 int64_t expected_pexe_size_; // Expected download total (-1 if unknown). | |
184 | |
185 // The helper thread used to do translations via SRPC. | |
186 // It accesses fields of PnaclCoordinator so it must have a | |
187 // shorter lifetime. | |
188 nacl::scoped_ptr<PnaclTranslateThread> translate_thread_; | |
189 }; | |
190 | |
191 //---------------------------------------------------------------------- | |
192 | |
193 } // namespace plugin; | |
194 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ | |
OLD | NEW |