| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Native Client 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_threads.h" | |
| 15 #include "native_client/src/shared/srpc/nacl_srpc.h" | |
| 16 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | |
| 17 #include "native_client/src/trusted/plugin/delayed_callback.h" | |
| 18 #include "native_client/src/trusted/plugin/nacl_subprocess.h" | |
| 19 #include "native_client/src/trusted/plugin/plugin_error.h" | |
| 20 #include "native_client/src/trusted/plugin/pnacl_thread_args.h" | |
| 21 | |
| 22 #include "ppapi/cpp/completion_callback.h" | |
| 23 | |
| 24 namespace plugin { | |
| 25 | |
| 26 class Plugin; | |
| 27 struct DoTranslateArgs; | |
| 28 struct DoLinkArgs; | |
| 29 | |
| 30 typedef std::pair<nacl::string, pp::CompletionCallback> url_callback_pair; | |
| 31 | |
| 32 // A class that handles PNaCl client-side translation. | |
| 33 // Usage: | |
| 34 // (1) Initialize(); | |
| 35 // (2) BitcodeToNative(bitcode, ..., finish_callback); | |
| 36 // (3) After finish_callback runs, do: | |
| 37 // fd = ReleaseTranslatedFD(); | |
| 38 // (4) go ahead and load the nexe from "fd" | |
| 39 // (5) delete | |
| 40 class PnaclCoordinator { | |
| 41 public: | |
| 42 PnaclCoordinator() | |
| 43 : instance_(NULL), | |
| 44 translate_notify_callback_(pp::BlockUntilComplete()), | |
| 45 llc_subprocess_(NULL), | |
| 46 ld_subprocess_(NULL), | |
| 47 obj_len_(-1), | |
| 48 translate_args_(NULL), | |
| 49 link_args_(NULL) { | |
| 50 } | |
| 51 | |
| 52 virtual ~PnaclCoordinator(); | |
| 53 | |
| 54 // Initialize() can only be called once during the lifetime of this instance. | |
| 55 void Initialize(Plugin* instance); | |
| 56 | |
| 57 void BitcodeToNative(const nacl::string& pexe_url, | |
| 58 const nacl::string& llc_url, | |
| 59 const nacl::string& ld_url, | |
| 60 const pp::CompletionCallback& finish_callback); | |
| 61 | |
| 62 // Call this to take ownership of the FD of the translated nexe after | |
| 63 // BitcodeToNative has completed (and the finish_callback called). | |
| 64 nacl::DescWrapper* ReleaseTranslatedFD() { | |
| 65 return translated_fd_.release(); | |
| 66 } | |
| 67 | |
| 68 // This method should really be private, but it is used to | |
| 69 // communicate with the linker thread. | |
| 70 NaClSrpcImcDescType GetLinkerResourceFD(const nacl::string& url) { | |
| 71 return linker_resource_fds_[url]->desc(); | |
| 72 } | |
| 73 | |
| 74 protected: | |
| 75 | |
| 76 void SetObjectFile(NaClSrpcImcDescType fd, int32_t len); | |
| 77 void SetTranslatedFile(NaClSrpcImcDescType fd); | |
| 78 | |
| 79 // Delay a callback until |num_dependencies| are met. | |
| 80 DelayedCallback* MakeDelayedCallback(pp::CompletionCallback cb, | |
| 81 uint32_t num_dependencies); | |
| 82 | |
| 83 // Helper function for generating callbacks that will be run when a | |
| 84 // download of |url| has completed. The generated callback will | |
| 85 // run |handler|. The |handler| itself is given a pp_error code, | |
| 86 // the url of the download, and another callback in the | |
| 87 // form of the supplied |delayed_callback|. | |
| 88 void AddDownloadToDelayedCallback( | |
| 89 void (PnaclCoordinator::*handler)(int32_t, | |
| 90 const nacl::string&, | |
| 91 DelayedCallback*), | |
| 92 DelayedCallback* delayed_callback, | |
| 93 const nacl::string& url, | |
| 94 std::vector<url_callback_pair>& queue); | |
| 95 | |
| 96 bool ScheduleDownload(const nacl::string& url, | |
| 97 const pp::CompletionCallback& cb); | |
| 98 | |
| 99 // Callbacks for when various files, etc. have been downloaded. | |
| 100 void PexeReady(int32_t pp_error, | |
| 101 const nacl::string& url, | |
| 102 DelayedCallback* delayed_callback); | |
| 103 void LLCReady(int32_t pp_error, | |
| 104 const nacl::string& url, | |
| 105 DelayedCallback* delayed_callback); | |
| 106 void LDReady(int32_t pp_error, | |
| 107 const nacl::string& url, | |
| 108 DelayedCallback* delayed_callback); | |
| 109 void LinkResourceReady(int32_t pp_error, | |
| 110 const nacl::string& url, | |
| 111 DelayedCallback* delayed_callback); | |
| 112 | |
| 113 int32_t GetLoadedFileDesc(int32_t pp_error, | |
| 114 const nacl::string& url, | |
| 115 const nacl::string& component); | |
| 116 | |
| 117 // Helper for starting helper nexes after they are downloaded. | |
| 118 NaClSubprocessId HelperNexeDidLoad(int32_t fd, ErrorInfo* error_info); | |
| 119 | |
| 120 // Callbacks for compute-based translation steps. | |
| 121 void RunTranslate(int32_t pp_error, DelayedCallback* delayed_callback); | |
| 122 void RunTranslateDidFinish(int32_t pp_error, | |
| 123 DelayedCallback* delayed_callback); | |
| 124 void RunLink(int32_t pp_error); | |
| 125 void RunLinkDidFinish(int32_t pp_error); | |
| 126 | |
| 127 // Pnacl translation completed normally. | |
| 128 void PnaclDidFinish(int32_t pp_error); | |
| 129 | |
| 130 // Run when faced with a PPAPI error condition. It brings control back to the | |
| 131 // plugin by invoking the |translate_notify_callback_|. | |
| 132 void PnaclPpapiError(int32_t pp_error); | |
| 133 | |
| 134 // Run |translate_notify_callback_| with an error condition that is not | |
| 135 // PPAPI specific. | |
| 136 void PnaclNonPpapiError(); | |
| 137 | |
| 138 // Wrapper for Plugin ReportLoadAbort. | |
| 139 void ReportLoadAbort(); | |
| 140 // Wrapper for Plugin ReportLoadError. | |
| 141 void ReportLoadError(const ErrorInfo& error); | |
| 142 | |
| 143 private: | |
| 144 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator); | |
| 145 | |
| 146 Plugin* instance_; | |
| 147 pp::CompletionCallback translate_notify_callback_; | |
| 148 pp::CompletionCallbackFactory<PnaclCoordinator> callback_factory_; | |
| 149 | |
| 150 // State for a single translation. | |
| 151 // TODO(jvoung): see if we can manage this state better, especially when we | |
| 152 // start having to translate multiple bitcode files for the same application | |
| 153 // (for DSOs). | |
| 154 | |
| 155 std::set<DelayedCallback*> delayed_callbacks; | |
| 156 | |
| 157 // Helper subprocess loaded by the plugin (deleted by the plugin). | |
| 158 // We may want to do cleanup ourselves when we are in the | |
| 159 // business of compiling multiple bitcode objects / libraries, and | |
| 160 // if we truly cannot reuse existing loaded subprocesses. | |
| 161 NaClSubprocess* llc_subprocess_; | |
| 162 NaClSubprocess* ld_subprocess_; | |
| 163 | |
| 164 // Bitcode file pulled from the Net. | |
| 165 nacl::scoped_ptr<nacl::DescWrapper> pexe_fd_; | |
| 166 | |
| 167 // Object "file" obtained after compiling with LLVM, along with the length | |
| 168 // of the "file". | |
| 169 nacl::scoped_ptr<nacl::DescWrapper> obj_fd_; | |
| 170 int32_t obj_len_; | |
| 171 | |
| 172 // Nexe from the final native Link. | |
| 173 nacl::scoped_ptr<nacl::DescWrapper> translated_fd_; | |
| 174 | |
| 175 // Perhaps make this a single thread that invokes (S)RPCs followed by | |
| 176 // callbacks based on a Queue of requests. A generic mechanism would make | |
| 177 // it easier to add steps later (the mechanism could look like PostMessage?). | |
| 178 nacl::scoped_ptr<DoTranslateArgs> translate_args_; | |
| 179 nacl::scoped_ptr<NaClThread> translate_thread_; | |
| 180 | |
| 181 nacl::scoped_ptr<DoLinkArgs> link_args_; | |
| 182 nacl::scoped_ptr<NaClThread> link_thread_; | |
| 183 | |
| 184 std::map<nacl::string, nacl::DescWrapper*> linker_resource_fds_; | |
| 185 }; | |
| 186 | |
| 187 //---------------------------------------------------------------------- | |
| 188 | |
| 189 } // namespace plugin; | |
| 190 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ | |
| OLD | NEW |