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.
5 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_
6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_
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"
15 #include "ppapi/cpp/completion_callback.h"
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"
21 #include "ppapi/utility/completion_callback_factory.h"
23 struct PP_PNaClOptions
;
28 class PnaclCoordinator
;
29 class PnaclTranslateThread
;
32 // A class invoked by Plugin to handle PNaCl client-side translation.
34 // (1) Invoke the factory method, e.g.,
35 // PnaclCoordinator* coord = BitcodeToNative(plugin,
36 // "http://foo.com/my.pexe",
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
44 // fd = coord->ReleaseTranslatedFD();
45 // (4) Load the nexe from "fd".
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
{
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();
58 // The factory method for translations.
59 static PnaclCoordinator
* BitcodeToNative(
61 const std::string
& pexe_url
,
62 const PP_PNaClOptions
& pnacl_options
,
63 const pp::CompletionCallback
& translate_notify_callback
);
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();
69 // Return a callback that should be notified when |bytes_compiled| bytes
70 // have been compiled.
71 pp::CompletionCallback
GetCompileProgressCallback(int64_t bytes_compiled
);
73 // Get the last known load progress.
74 void GetCurrentProgress(int64_t* bytes_loaded
, int64_t* bytes_total
);
76 // Return true if we should delay the progress event reporting.
77 // This delay approximates:
78 // - the size of the buffer of bytes sent but not-yet-compiled by LLC.
79 // - the linking time.
80 bool ShouldDelayProgressEvent() {
81 const uint32_t kProgressEventSlopPct
= 5;
82 return ((expected_pexe_size_
- pexe_bytes_compiled_
) * 100 /
83 expected_pexe_size_
) < kProgressEventSlopPct
;
87 void BitcodeStreamCacheHit(PP_FileHandle handle
);
88 void BitcodeStreamCacheMiss(int64_t expected_pexe_size
,
89 PP_FileHandle handle
);
91 // Invoked when a pexe data chunk arrives (when using streaming translation)
92 void BitcodeStreamGotData(const void* data
, int32_t length
);
94 // Invoked when the pexe download finishes (using streaming translation)
95 void BitcodeStreamDidFinish(int32_t pp_error
);
98 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator
);
100 // BitcodeToNative is the factory method for PnaclCoordinators.
101 // Therefore the constructor is private.
102 PnaclCoordinator(Plugin
* plugin
,
103 const std::string
& pexe_url
,
104 const PP_PNaClOptions
& pnacl_options
,
105 const pp::CompletionCallback
& translate_notify_callback
);
107 // Invoke to issue a GET request for bitcode.
108 void OpenBitcodeStream();
110 // Invoked when a pexe data chunk is compiled.
111 void BitcodeGotCompiled(int32_t pp_error
, int64_t bytes_compiled
);
112 // Once llc and ld nexes have been loaded and the two temporary files have
113 // been created, this starts the translation. Translation starts two
114 // subprocesses, one for llc and one for ld.
115 void RunTranslate(int32_t pp_error
);
117 // Invoked when translation is finished.
118 void TranslateFinished(int32_t pp_error
);
120 // Invoked when the read descriptor for nexe_file_ is created.
121 void NexeReadDidOpen(int32_t pp_error
);
123 // Bring control back to the plugin by invoking the
124 // |translate_notify_callback_|. This does not set the ErrorInfo report,
125 // it is assumed that it was already set.
126 void ExitWithError();
127 // Run |translate_notify_callback_| with an error condition that is not
128 // PPAPI specific. Also set ErrorInfo report.
129 void ReportNonPpapiError(PP_NaClError err
, const std::string
& message
);
130 // Run when faced with a PPAPI error condition. Bring control back to the
131 // plugin by invoking the |translate_notify_callback_|.
132 // Also set ErrorInfo report.
133 void ReportPpapiError(PP_NaClError err
,
134 int32_t pp_error
, const std::string
& message
);
137 // Keeps track of the pp_error upon entry to TranslateFinished,
138 // for inspection after cleanup.
139 int32_t translate_finish_error_
;
141 // The plugin owning the nexe for which we are doing translation.
144 pp::CompletionCallback translate_notify_callback_
;
145 // Set to true when the translation (if applicable) is finished and the nexe
146 // file is loaded, (or when there was an error), and the browser has been
147 // notified via ReportTranslationFinished. If it is not set before
148 // plugin/coordinator destruction, the destructor will call
149 // ReportTranslationFinished.
150 bool translation_finished_reported_
;
151 // Threadsafety is required to support file lookups.
152 pp::CompletionCallbackFactory
<PnaclCoordinator
,
153 pp::ThreadSafeThreadTraits
> callback_factory_
;
155 // An auxiliary class that manages downloaded resources (llc and ld nexes).
156 nacl::scoped_ptr
<PnaclResources
> resources_
;
158 // The URL for the pexe file.
159 std::string pexe_url_
;
160 // Options for translation.
161 PP_PNaClOptions pnacl_options_
;
162 // Architecture-specific attributes used for translation. These are
163 // supplied by Chrome, not the developer, and are therefore different
164 // from PNaCl options.
165 std::string architecture_attributes_
;
167 // Object file, produced by the translator and consumed by the linker.
168 std::vector
<TempFile
*> obj_files_
;
169 nacl::scoped_ptr
<nacl::DescWrapper
> invalid_desc_wrapper_
;
170 // Number of split modules (threads) for llc
171 int split_module_count_
;
173 // Translated nexe file, produced by the linker.
174 nacl::scoped_ptr
<TempFile
> temp_nexe_file_
;
176 // Used to report information when errors (PPAPI or otherwise) are reported.
177 ErrorInfo error_info_
;
179 // True if an error was already reported, and translate_notify_callback_
180 // was already run/consumed.
181 bool error_already_reported_
;
183 // State for timing and size information for UMA stats.
184 int64_t pexe_size_
; // Count as we stream -- will converge to pexe size.
185 int64_t pexe_bytes_compiled_
; // Count as we compile.
186 int64_t expected_pexe_size_
; // Expected download total (-1 if unknown).
188 // The helper thread used to do translations via SRPC.
189 // It accesses fields of PnaclCoordinator so it must have a
191 nacl::scoped_ptr
<PnaclTranslateThread
> translate_thread_
;
194 //----------------------------------------------------------------------
196 } // namespace plugin;
197 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_