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