Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ppapi / native_client / src / trusted / plugin / pnacl_coordinator.h
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 <set>
9 #include <map>
10 #include <vector>
11
12 #include "native_client/src/include/nacl_macros.h"
13 #include "native_client/src/include/nacl_string.h"
14 #include "native_client/src/shared/platform/nacl_sync_raii.h"
15 #include "native_client/src/shared/srpc/nacl_srpc.h"
16 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
17
18 #include "ppapi/cpp/completion_callback.h"
19
20 #include "ppapi/native_client/src/trusted/plugin/callback_source.h"
21 #include "ppapi/native_client/src/trusted/plugin/file_downloader.h"
22 #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h"
23 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
24 #include "ppapi/native_client/src/trusted/plugin/pnacl_options.h"
25 #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h"
26
27
28 namespace plugin {
29
30 class Manifest;
31 class Plugin;
32 class PnaclCoordinator;
33 class PnaclTranslateThread;
34 class TempFile;
35
36 // A class invoked by Plugin to handle PNaCl client-side translation.
37 // Usage:
38 // (1) Invoke the factory method, e.g.,
39 //     PnaclCoordinator* coord = BitcodeToNative(plugin,
40 //                                               "http://foo.com/my.pexe",
41 //                                               pnacl_options,
42 //                                               TranslateNotifyCallback);
43 // (2) TranslateNotifyCallback gets invoked when translation is complete.
44 //     If the translation was successful, the pp_error argument is PP_OK.
45 //     Other values indicate errors.
46 // (3) After finish_callback runs, get the file descriptor of the translated
47 //     nexe, e.g.,
48 //     fd = coord->ReleaseTranslatedFD();
49 // (4) Load the nexe from "fd".
50 // (5) delete coord.
51 //
52 // Translation proceeds in two steps:
53 // (1) llc translates the bitcode in pexe_url_ to an object in obj_file_.
54 // (2) ld links the object code in obj_file_ and produces a nexe in nexe_file_.
55 //
56 // The coordinator proceeds through several states.  They are
57 // OPEN_BITCODE_STREAM
58 //       Complete when BitcodeStreamDidOpen is invoked
59 // LOAD_TRANSLATOR_BINARIES
60 //     Complete when ResourcesDidLoad is invoked.
61 // GET_NEXE_FD
62 //       Get an FD which contains the cached nexe, or is writeable for
63 //       translation output. Complete when NexeFdDidOpen is called.
64 //
65 // If there was a cache hit, go to OPEN_NEXE_FOR_SEL_LDR, otherwise,
66 // continue streaming the bitcode, and:
67 // OPEN_TMP_FOR_LLC_TO_LD_COMMUNICATION
68 //     Complete when ObjectFileDidOpen is invoked.
69 // OPEN_NEXE_FD_FOR_WRITING
70 //     Complete when RunTranslate is invoked.
71 // START_LD_AND_LLC_SUBPROCESS_AND_INITIATE_TRANSLATION
72 //     Complete when RunTranslate returns.
73 // TRANSLATION_COMPLETE
74 //     Complete when TranslateFinished is invoked.
75 //
76 // OPEN_NEXE_FOR_SEL_LDR
77 //   Complete when NexeReadDidOpen is invoked.
78 class PnaclCoordinator: public CallbackSource<FileStreamData> {
79  public:
80   // Maximum number of object files passable to the translator. Cannot be
81   // changed without changing the RPC signatures.
82   const static size_t kMaxTranslatorObjectFiles = 16;
83   virtual ~PnaclCoordinator();
84
85   // The factory method for translations.
86   static PnaclCoordinator* BitcodeToNative(
87       Plugin* plugin,
88       const nacl::string& pexe_url,
89       const PnaclOptions& pnacl_options,
90       const pp::CompletionCallback& translate_notify_callback);
91
92   // Call this to take ownership of the FD of the translated nexe after
93   // BitcodeToNative has completed (and the finish_callback called).
94   nacl::DescWrapper* ReleaseTranslatedFD();
95
96   // Run |translate_notify_callback_| with an error condition that is not
97   // PPAPI specific.  Also set ErrorInfo report.
98   void ReportNonPpapiError(PluginErrorCode err, const nacl::string& message);
99   // Run when faced with a PPAPI error condition. Bring control back to the
100   // plugin by invoking the |translate_notify_callback_|.
101   // Also set ErrorInfo report.
102   void ReportPpapiError(PluginErrorCode err,
103                         int32_t pp_error, const nacl::string& message);
104   // Bring control back to the plugin by invoking the
105   // |translate_notify_callback_|.  This does not set the ErrorInfo report,
106   // it is assumed that it was already set.
107   void ExitWithError();
108
109   // Implement FileDownloader's template of the CallbackSource interface.
110   // This method returns a callback which will be called by the FileDownloader
111   // to stream the bitcode data as it arrives. The callback
112   // (BitcodeStreamGotData) passes it to llc over SRPC.
113   StreamCallback GetCallback();
114
115   // Return a callback that should be notified when |bytes_compiled| bytes
116   // have been compiled.
117   pp::CompletionCallback GetCompileProgressCallback(int64_t bytes_compiled);
118
119   // Get the last known load progress.
120   void GetCurrentProgress(int64_t* bytes_loaded, int64_t* bytes_total);
121
122   // Return true if the total progress to report (w/ progress events) is known.
123   bool ExpectedProgressKnown() { return expected_pexe_size_ != -1; }
124
125   // Return true if we should delay the progress event reporting.
126   // This delay approximates:
127   // - the size of the buffer of bytes sent but not-yet-compiled by LLC.
128   // - the linking time.
129   bool ShouldDelayProgressEvent() {
130     const uint32_t kProgressEventSlopPct = 5;
131     return ((expected_pexe_size_ - pexe_bytes_compiled_) * 100 /
132             expected_pexe_size_) < kProgressEventSlopPct;
133   }
134
135  private:
136   NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator);
137
138   // BitcodeToNative is the factory method for PnaclCoordinators.
139   // Therefore the constructor is private.
140   PnaclCoordinator(Plugin* plugin,
141                    const nacl::string& pexe_url,
142                    const PnaclOptions& pnacl_options,
143                    const pp::CompletionCallback& translate_notify_callback);
144
145   // Invoke to issue a GET request for bitcode.
146   void OpenBitcodeStream();
147   // Invoked when we've started an URL fetch for the pexe to check for
148   // caching metadata.
149   void BitcodeStreamDidOpen(int32_t pp_error);
150
151   // Callback for when the resource info JSON file has been read.
152   void ResourceInfoWasRead(int32_t pp_error);
153
154   // Callback for when llc and ld have been downloaded.
155   void ResourcesDidLoad(int32_t pp_error);
156   // Invoked when we've gotten a temp FD for the nexe, either with the nexe
157   // data, or a writeable fd to save to.
158   void NexeFdDidOpen(int32_t pp_error);
159   // Invoked when a pexe data chunk arrives (when using streaming translation)
160   void BitcodeStreamGotData(int32_t pp_error, FileStreamData data);
161   // Invoked when a pexe data chunk is compiled.
162   void BitcodeGotCompiled(int32_t pp_error, int64_t bytes_compiled);
163   // Invoked when the pexe download finishes (using streaming translation)
164   void BitcodeStreamDidFinish(int32_t pp_error);
165   // Invoked when the write descriptor for obj_file_ is created.
166   void ObjectFileDidOpen(int32_t pp_error);
167   // Once llc and ld nexes have been loaded and the two temporary files have
168   // been created, this starts the translation.  Translation starts two
169   // subprocesses, one for llc and one for ld.
170   void RunTranslate(int32_t pp_error);
171
172   // Invoked when translation is finished.
173   void TranslateFinished(int32_t pp_error);
174
175   // Invoked when the read descriptor for nexe_file_ is created.
176   void NexeReadDidOpen(int32_t pp_error);
177
178   // Keeps track of the pp_error upon entry to TranslateFinished,
179   // for inspection after cleanup.
180   int32_t translate_finish_error_;
181
182   // The plugin owning the nexe for which we are doing translation.
183   Plugin* plugin_;
184
185   pp::CompletionCallback translate_notify_callback_;
186   // Set to true when the translation (if applicable) is finished and the nexe
187   // file is loaded, (or when there was an error), and the browser has been
188   // notified via ReportTranslationFinished. If it is not set before
189   // plugin/coordinator destruction, the destructor will call
190   // ReportTranslationFinished.
191   bool translation_finished_reported_;
192   // Threadsafety is required to support file lookups.
193   pp::CompletionCallbackFactory<PnaclCoordinator,
194                                 pp::ThreadSafeThreadTraits> callback_factory_;
195
196   // The manifest used by resource loading and ld + llc's reverse service
197   // to look up objects and libraries.
198   nacl::scoped_ptr<const Manifest> manifest_;
199   // An auxiliary class that manages downloaded resources (llc and ld nexes).
200   nacl::scoped_ptr<PnaclResources> resources_;
201
202   // The URL for the pexe file.
203   nacl::string pexe_url_;
204   // Options for translation.
205   PnaclOptions pnacl_options_;
206
207   // Object file, produced by the translator and consumed by the linker.
208   std::vector<TempFile*> obj_files_;
209   nacl::scoped_ptr<nacl::DescWrapper> invalid_desc_wrapper_;
210   // Number of split modules (threads) for llc
211   int split_module_count_;
212   int num_object_files_opened_;
213
214   // Translated nexe file, produced by the linker.
215   nacl::scoped_ptr<TempFile> temp_nexe_file_;
216   // Passed to the browser, which sets it to true if there is a translation
217   // cache hit.
218   PP_Bool is_cache_hit_;
219
220   // Downloader for streaming translation
221   nacl::scoped_ptr<FileDownloader> streaming_downloader_;
222
223   // Used to report information when errors (PPAPI or otherwise) are reported.
224   ErrorInfo error_info_;
225
226   // True if an error was already reported, and translate_notify_callback_
227   // was already run/consumed.
228   bool error_already_reported_;
229
230   // State for timing and size information for UMA stats.
231   int64_t pnacl_init_time_;
232   int64_t pexe_size_;  // Count as we stream -- will converge to pexe size.
233   int64_t pexe_bytes_compiled_;  // Count as we compile.
234   int64_t expected_pexe_size_;   // Expected download total (-1 if unknown).
235
236   // The helper thread used to do translations via SRPC.
237   // Keep this last in declaration order to ensure the other variables
238   // haven't been destroyed yet when its destructor runs.
239   nacl::scoped_ptr<PnaclTranslateThread> translate_thread_;
240 };
241
242 //----------------------------------------------------------------------
243
244 }  // namespace plugin;
245 #endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_