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