Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ | 5 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ |
| 6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ | 6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ |
| 7 | 7 |
| 8 #include <set> | 8 #include <set> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "native_client/src/include/nacl_macros.h" | 12 #include "native_client/src/include/nacl_macros.h" |
| 13 #include "native_client/src/include/nacl_string.h" | 13 #include "native_client/src/include/nacl_string.h" |
| 14 #include "native_client/src/shared/platform/nacl_sync_checked.h" | 14 #include "native_client/src/shared/platform/nacl_sync_checked.h" |
| 15 #include "native_client/src/shared/platform/nacl_threads.h" | 15 #include "native_client/src/shared/platform/nacl_threads.h" |
| 16 #include "native_client/src/shared/srpc/nacl_srpc.h" | 16 #include "native_client/src/shared/srpc/nacl_srpc.h" |
| 17 #include "native_client/src/trusted/desc/nacl_desc_rng.h" | |
| 17 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | 18 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
| 18 #include "native_client/src/trusted/plugin/delayed_callback.h" | 19 #include "native_client/src/trusted/plugin/delayed_callback.h" |
| 19 #include "native_client/src/trusted/plugin/nacl_subprocess.h" | 20 #include "native_client/src/trusted/plugin/nacl_subprocess.h" |
| 20 #include "native_client/src/trusted/plugin/plugin_error.h" | 21 #include "native_client/src/trusted/plugin/plugin_error.h" |
| 21 #include "native_client/src/trusted/plugin/pnacl_resources.h" | 22 #include "native_client/src/trusted/plugin/pnacl_resources.h" |
| 22 | 23 |
| 24 #include "ppapi/c/pp_file_info.h" | |
| 23 #include "ppapi/cpp/completion_callback.h" | 25 #include "ppapi/cpp/completion_callback.h" |
| 26 #include "ppapi/cpp/file_io.h" | |
| 27 #include "ppapi/cpp/file_ref.h" | |
| 28 #include "ppapi/cpp/file_system.h" | |
| 24 | 29 |
| 25 struct NaClMutex; | 30 struct NaClMutex; |
| 31 struct PPB_FileIOTrusted; | |
| 26 | 32 |
| 27 namespace plugin { | 33 namespace plugin { |
| 28 | 34 |
| 29 class Plugin; | 35 class Plugin; |
| 30 class PnaclCoordinator; | 36 class PnaclCoordinator; |
| 31 | 37 |
| 38 // Represents a file used as a temporary between stages in translation. | |
|
robertm
2011/12/12 16:23:29
Maybe add a more concrete use example so that the
sehr (please use chromium)
2011/12/13 00:12:45
I hope what I have added is sufficient.
| |
| 39 class PnaclFileDescPair { | |
| 40 public: | |
| 41 PnaclFileDescPair(pp::FileSystem* file_system, PnaclCoordinator* coordinator); | |
| 42 ~PnaclFileDescPair(); | |
| 43 // Opens a pair of file IO objects referring to a randomly named file in | |
| 44 // file_system_. One IO is for writing the file and another for reading it. | |
| 45 void Open(const pp::CompletionCallback& cb); | |
| 46 // Gets the POSIX file descriptor for a resource. | |
| 47 int32_t GetFD(int32_t pp_error, | |
| 48 const pp::Resource& resource, | |
| 49 const nacl::string& component); | |
| 50 // Called when the writable file IO was opened. | |
| 51 void WriteFileDidOpen(int32_t pp_error); | |
| 52 // Called when the readable file IO was opened. | |
| 53 void ReadFileDidOpen(int32_t pp_error); | |
| 54 | |
| 55 // Accessors. | |
| 56 nacl::DescWrapper* write_wrapper() { return write_wrapper_.get(); } | |
| 57 nacl::DescWrapper* read_wrapper() { return read_wrapper_.get(); } | |
| 58 | |
| 59 private: | |
| 60 pp::FileSystem* file_system_; | |
| 61 PnaclCoordinator* coordinator_; | |
| 62 const PPB_FileIOTrusted* file_io_trusted_; | |
| 63 pp::CompletionCallbackFactory<PnaclFileDescPair> callback_factory_; | |
| 64 nacl::string filename_; | |
| 65 nacl::scoped_ptr<pp::FileRef> write_ref_; | |
| 66 nacl::scoped_ptr<pp::FileIO> write_io_; | |
| 67 nacl::scoped_ptr<nacl::DescWrapper> write_wrapper_; | |
| 68 nacl::scoped_ptr<pp::FileRef> read_ref_; | |
| 69 nacl::scoped_ptr<pp::FileIO> read_io_; | |
| 70 nacl::scoped_ptr<nacl::DescWrapper> read_wrapper_; | |
| 71 pp::CompletionCallback done_callback_; | |
| 72 // Random number generator used to create filenames. | |
| 73 struct NaClDescRng rng_desc_; | |
| 74 }; | |
| 75 | |
| 76 // A reference counting class that can be used for one background thread. | |
| 77 // The default NonThreadSafeRefCount asserts that it is only used on the | |
| 78 // main thread. Needed for CompletionCallbackFactory in PnaclTranslationUnit. | |
| 79 class PnaclNonThreadSafeRefCount { | |
|
robertm
2011/12/12 16:23:29
the point of this class seems dubious as it does
sehr (please use chromium)
2011/12/13 00:12:45
After fusing the two classes, it needed to be sync
| |
| 80 public: | |
| 81 PnaclNonThreadSafeRefCount() : ref_(0) { } | |
| 82 int32_t AddRef() { return ++ref_; } | |
| 83 int32_t Release() { return --ref_; } | |
| 84 | |
| 85 private: | |
| 86 int32_t ref_; | |
| 87 }; | |
| 88 | |
| 89 // Represents an individual bitcode file during a translation. | |
| 32 struct PnaclTranslationUnit { | 90 struct PnaclTranslationUnit { |
|
robertm
2011/12/12 16:23:29
why a struct?
sehr (please use chromium)
2011/12/13 00:12:45
I eliminated this struct by merging it into PnaclC
| |
| 33 PnaclTranslationUnit(PnaclCoordinator* coord) | 91 public: |
| 92 PnaclTranslationUnit(PnaclCoordinator* coord, const nacl::string& url) | |
| 34 : coordinator(coord), | 93 : coordinator(coord), |
| 35 obj_len(-1), | 94 pexe_url(url) { |
| 36 is_shared_library(false), | 95 NaClXMutexCtor(&mu); |
| 37 soname(""), | 96 NaClXCondVarCtor(&cv); |
| 38 lib_dependencies("") { | 97 callback_factory.Initialize(this); |
| 39 } | 98 } |
| 40 // Punch hole in abstraction. | 99 |
| 100 // Invoked on the main thread on behalf of the lookup service to start | |
| 101 // loading a particular URL. | |
| 102 void LoadOneFile(int32_t pp_error, | |
| 103 const nacl::string& url, | |
| 104 nacl::DescWrapper** wrapper, | |
| 105 pp::CompletionCallback& done_cb); | |
| 106 // Invoked by the renderer when the file was loaded. | |
| 107 void DidLoadFile(int32_t pp_error, | |
| 108 const nacl::string& full_url, | |
| 109 nacl::DescWrapper** wrapper, | |
| 110 pp::CompletionCallback& done_cb); | |
| 111 // Signals the waiting lookup service to resume. | |
| 112 void ResumeLookup(int32_t pp_error, PnaclTranslationUnit* trans); | |
| 113 // Performs the lookup of the descriptor for url. | |
| 114 nacl::DescWrapper* LookupDesc(const nacl::string& url); | |
| 115 | |
| 116 // To refer back to shared resources. | |
| 41 PnaclCoordinator* coordinator; | 117 PnaclCoordinator* coordinator; |
| 42 | 118 // The URL for the pexe file. |
| 119 nacl::string pexe_url; | |
| 120 // Factory for callbacks used in file lookups. | |
| 121 pp::CompletionCallbackFactory<PnaclTranslationUnit, | |
| 122 PnaclNonThreadSafeRefCount> callback_factory; | |
| 43 // Borrowed reference which must outlive the thread. | 123 // Borrowed reference which must outlive the thread. |
| 44 nacl::scoped_ptr<nacl::DescWrapper> pexe_wrapper; | 124 nacl::scoped_ptr<nacl::DescWrapper> pexe_wrapper; |
| 45 | 125 // Object file, produced by the translator and consumed by the linker. |
| 46 // Object file produced by translator and consumed by the linker. | 126 nacl::scoped_ptr<PnaclFileDescPair> obj_file; |
| 47 nacl::scoped_ptr<nacl::DescWrapper> obj_wrapper; | 127 // Translated nexe file, produced by the linker and consumed by sel_ldr. |
| 48 int32_t obj_len; | 128 nacl::scoped_ptr<PnaclFileDescPair> nexe_file; |
| 49 | |
| 50 // Information extracted from the pexe that is needed by the linker. | |
| 51 bool is_shared_library; | |
| 52 nacl::string soname; | |
| 53 nacl::string lib_dependencies; | |
| 54 | |
| 55 // The translated user nexe file. | |
| 56 nacl::scoped_ptr<nacl::DescWrapper> nexe_wrapper; | |
| 57 | |
| 58 // Callbacks to run when tasks or completed or an error has occurred. | 129 // Callbacks to run when tasks or completed or an error has occurred. |
| 59 pp::CompletionCallback translate_done_cb; | 130 pp::CompletionCallback translate_done_cb; |
| 60 pp::CompletionCallback link_done_cb; | 131 |
| 132 // Support for file lookups. | |
| 133 struct NaClMutex mu; | |
|
robertm
2011/12/12 16:23:29
these should be private if possible
sehr (please use chromium)
2011/12/13 00:12:45
Done.
| |
| 134 struct NaClCondVar cv; | |
| 135 bool lookup_is_complete; | |
| 61 | 136 |
| 62 ErrorInfo error_info; | 137 ErrorInfo error_info; |
| 63 }; | 138 }; |
| 64 | 139 |
| 65 | 140 |
| 66 typedef std::pair<nacl::string, pp::CompletionCallback> url_callback_pair; | 141 // typedef std::pair<nacl::string, pp::CompletionCallback> url_callback_pair; |
| 142 typedef std::vector<nacl::string> string_vector; | |
| 67 | 143 |
| 68 // A class that handles PNaCl client-side translation. | 144 // A class that handles PNaCl client-side translation. |
| 69 // Usage: | 145 // Usage: |
|
robertm
2011/12/12 16:23:29
since we do not have a design the class comment wo
sehr (please use chromium)
2011/12/13 00:12:45
Done.
| |
| 70 // (1) Initialize(); | 146 // (1) Initialize(); |
| 71 // (2) BitcodeToNative(bitcode, ..., finish_callback); | 147 // (2) BitcodeToNative(bitcode, ..., finish_callback); |
| 72 // (3) After finish_callback runs, do: | 148 // (3) After finish_callback runs, do: |
| 73 // fd = ReleaseTranslatedFD(); | 149 // fd = ReleaseTranslatedFD(); |
| 74 // (4) go ahead and load the nexe from "fd" | 150 // (4) go ahead and load the nexe from "fd" |
| 75 // (5) delete | 151 // (5) delete |
| 76 class PnaclCoordinator { | 152 class PnaclCoordinator { |
| 77 public: | 153 public: |
| 78 PnaclCoordinator() | 154 PnaclCoordinator() |
| 79 : plugin_(NULL), | 155 : plugin_(NULL), |
| 80 translate_notify_callback_(pp::BlockUntilComplete()), | 156 translate_notify_callback_(pp::BlockUntilComplete()), |
| 81 llc_subprocess_(NULL), | 157 llc_subprocess_(NULL), |
| 82 ld_subprocess_(NULL), | 158 ld_subprocess_(NULL), |
| 83 subprocesses_should_die_(false) { | 159 subprocesses_should_die_(false), |
| 160 file_system_is_initialized_(false) { | |
| 84 NaClXMutexCtor(&subprocess_mu_); | 161 NaClXMutexCtor(&subprocess_mu_); |
| 85 } | 162 } |
| 86 | 163 |
| 87 virtual ~PnaclCoordinator(); | 164 virtual ~PnaclCoordinator(); |
| 88 | 165 |
| 89 // Initialize() can only be called once during the lifetime of this instance. | 166 // Initialize() can only be called once during the lifetime of this instance. |
| 90 void Initialize(Plugin* instance); | 167 void Initialize(Plugin* instance); |
| 91 | 168 |
| 92 void BitcodeToNative(const nacl::string& pexe_url, | 169 void BitcodeToNative(const nacl::string& pexe_url, |
| 93 const pp::CompletionCallback& finish_callback); | 170 const pp::CompletionCallback& finish_callback); |
| 94 | 171 |
| 95 // Call this to take ownership of the FD of the translated nexe after | 172 // Call this to take ownership of the FD of the translated nexe after |
| 96 // BitcodeToNative has completed (and the finish_callback called). | 173 // BitcodeToNative has completed (and the finish_callback called). |
| 97 nacl::DescWrapper* ReleaseTranslatedFD() { | 174 nacl::DescWrapper* ReleaseTranslatedFD() { |
| 98 return translated_fd_.release(); | 175 return translated_fd_.release(); |
| 99 } | 176 } |
| 100 | 177 |
| 101 int32_t GetLoadedFileDesc(int32_t pp_error, | 178 int32_t GetLoadedFileDesc(int32_t pp_error, |
|
robertm
2011/12/12 16:23:29
comment this prototype
sehr (please use chromium)
2011/12/13 00:12:45
Done.
| |
| 102 const nacl::string& url, | 179 const nacl::string& url, |
| 103 const nacl::string& component); | 180 const nacl::string& component); |
| 104 | 181 |
| 105 // Run when faced with a PPAPI error condition. It brings control back to the | |
| 106 // plugin by invoking the |translate_notify_callback_|. | |
| 107 void PnaclPpapiError(int32_t pp_error); | |
| 108 // Run |translate_notify_callback_| with an error condition that is not | 182 // Run |translate_notify_callback_| with an error condition that is not |
| 109 // PPAPI specific. | 183 // PPAPI specific. |
| 110 void PnaclNonPpapiError(); | 184 void ReportNonPpapiError(const nacl::string& message); |
| 111 // Wrapper for Plugin ReportLoadAbort. | 185 // Run when faced with a PPAPI error condition. Bring control back to the |
| 112 void ReportLoadAbort(); | 186 // plugin by invoking the |translate_notify_callback_|. |
| 113 // Wrapper for Plugin ReportLoadError. | 187 void ReportPpapiError(int32_t pp_error, const nacl::string& message); |
| 114 void ReportLoadError(const ErrorInfo& error); | 188 void ReportPpapiError(int32_t pp_error, const ErrorInfo& error); |
| 115 | 189 |
| 116 // Accessors for use by helper threads. | 190 // Accessors for use by helper threads. |
|
robertm
2011/12/12 16:23:29
can these be avoided? many seem to be used
during
sehr (please use chromium)
2011/12/13 00:12:45
Fusing PnaclTranslationUnit into PnaclCoordinator
| |
| 117 nacl::string resource_base_url() const { return resource_base_url_; } | 191 nacl::string resource_base_url() const { return resource_base_url_; } |
| 192 PnaclResources* resources() const { return resources_.get(); } | |
| 118 Plugin* plugin() const { return plugin_; } | 193 Plugin* plugin() const { return plugin_; } |
| 119 nacl::string llc_url() const { return llc_url_; } | |
| 120 NaClSubprocess* llc_subprocess() const { return llc_subprocess_; } | 194 NaClSubprocess* llc_subprocess() const { return llc_subprocess_; } |
| 121 bool StartLlcSubProcess(); | |
| 122 nacl::string ld_url() const { return ld_url_; } | |
| 123 NaClSubprocess* ld_subprocess() const { return ld_subprocess_; } | 195 NaClSubprocess* ld_subprocess() const { return ld_subprocess_; } |
| 124 bool StartLdSubProcess(); | 196 NaClSubprocess* StartSubProcess(const nacl::string& url); |
| 125 bool SubprocessesShouldDie(); | 197 bool SubprocessesShouldDie(); |
| 126 void SetSubprocessesShouldDie(bool subprocesses_should_die); | 198 void SetSubprocessesShouldDie(bool subprocesses_should_die); |
| 127 PnaclResources* resources() const { return resources_.get(); } | |
| 128 | 199 |
| 129 protected: | 200 protected: |
|
robertm
2011/12/12 16:23:29
protected vs private is very
subtle, please add c
sehr (please use chromium)
2011/12/13 00:12:45
There are no child classes, so I moved all this to
| |
| 201 // Callback for when various files, etc. have been downloaded. | |
| 202 void ResourcesDidLoad(int32_t pp_error); | |
| 130 | 203 |
| 131 // Callbacks for when various files, etc. have been downloaded. | 204 // Callbacks for temporary file related stages. |
| 132 void ResourcesDidLoad(int32_t pp_error, | 205 void FileSystemDidOpen(int32_t pp_error); |
| 133 const nacl::string& url, | 206 void ObjectPairDidOpen(int32_t pp_error, PnaclTranslationUnit* translation); |
| 134 PnaclTranslationUnit* translation_unit); | 207 void NexePairDidOpen(int32_t pp_error, PnaclTranslationUnit* translation); |
| 135 | 208 |
| 136 // Callbacks for compute-based translation steps. | 209 // Callbacks for compute-based translation steps. |
| 137 void RunTranslate(int32_t pp_error, | 210 void DoStartTranslation(int32_t pp_error, PnaclTranslationUnit* translation); |
| 138 const nacl::string& url, | 211 void RunTranslate(int32_t pp_error, PnaclTranslationUnit* translation_unit); |
| 139 PnaclTranslationUnit* translation_unit); | |
| 140 void RunLink(int32_t pp_error, PnaclTranslationUnit* translation_unit); | 212 void RunLink(int32_t pp_error, PnaclTranslationUnit* translation_unit); |
| 141 | 213 |
| 142 // Pnacl translation completed normally. | 214 // Pnacl translation completed normally. |
| 143 void PnaclDidFinish(int32_t pp_error, PnaclTranslationUnit* translation_unit); | 215 void PnaclDidFinish(int32_t pp_error, PnaclTranslationUnit* translation_unit); |
| 144 | 216 |
| 145 private: | 217 private: |
| 146 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator); | 218 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator); |
| 147 | 219 |
| 148 Plugin* plugin_; | 220 Plugin* plugin_; |
| 149 pp::CompletionCallback translate_notify_callback_; | 221 pp::CompletionCallback translate_notify_callback_; |
| 150 pp::CompletionCallbackFactory<PnaclCoordinator> callback_factory_; | 222 pp::CompletionCallbackFactory<PnaclCoordinator> callback_factory_; |
| 151 | 223 |
| 152 // URLs used to lookup downloaded resources. | 224 // URLs used to lookup downloaded resources. |
| 153 nacl::string resource_base_url_; | 225 nacl::string resource_base_url_; |
| 154 nacl::string llc_url_; | |
| 155 nacl::string ld_url_; | |
| 156 | 226 |
| 157 // Helper subprocesses loaded by the plugin (deleted by the plugin). | 227 // Helper subprocesses loaded by the plugin (deleted by the plugin). |
|
robertm
2011/12/12 16:23:29
please comment all variables and add any informati
sehr (please use chromium)
2011/12/13 00:12:45
Done.
| |
| 158 // We may want to do cleanup ourselves when we are in the | 228 // We may want to do cleanup ourselves when we are in the |
| 159 // business of compiling multiple bitcode objects / libraries, and | 229 // business of compiling multiple bitcode objects / libraries, and |
| 160 // if we truly cannot reuse existing loaded subprocesses. | 230 // if we truly cannot reuse existing loaded subprocesses. |
| 161 NaClSubprocess* llc_subprocess_; | 231 NaClSubprocess* llc_subprocess_; |
| 162 NaClSubprocess* ld_subprocess_; | 232 NaClSubprocess* ld_subprocess_; |
| 163 bool subprocesses_should_die_; | 233 bool subprocesses_should_die_; |
| 164 struct NaClMutex subprocess_mu_; | 234 struct NaClMutex subprocess_mu_; |
| 165 | 235 |
| 166 // Nexe from the final native Link. | 236 // Nexe from the final native Link. |
| 167 nacl::scoped_ptr<nacl::DescWrapper> translated_fd_; | 237 nacl::scoped_ptr<nacl::DescWrapper> translated_fd_; |
| 168 | 238 |
| 169 // Perhaps make this a single thread that invokes (S)RPCs followed by | 239 // Perhaps make this a single thread that invokes (S)RPCs followed by |
| 170 // callbacks based on a Queue of requests. A generic mechanism would make | 240 // callbacks based on a Queue of requests. A generic mechanism would make |
| 171 // it easier to add steps later (the mechanism could look like PostMessage?). | 241 // it easier to add steps later (the mechanism could look like PostMessage?). |
| 172 nacl::scoped_ptr<PnaclTranslationUnit> translation_unit_; | 242 nacl::scoped_ptr<PnaclTranslationUnit> translation_unit_; |
| 173 nacl::scoped_ptr<NaClThread> translate_thread_; | 243 nacl::scoped_ptr<NaClThread> translate_thread_; |
| 174 nacl::scoped_ptr<NaClThread> link_thread_; | 244 // Translation creates local temporary files. |
| 175 | 245 nacl::scoped_ptr<pp::FileSystem> file_system_; |
| 246 bool file_system_is_initialized_; | |
| 176 // An auxiliary class that manages downloaded resources. | 247 // An auxiliary class that manages downloaded resources. |
| 177 nacl::scoped_ptr<PnaclResources> resources_; | 248 nacl::scoped_ptr<PnaclResources> resources_; |
| 178 }; | 249 }; |
| 179 | 250 |
| 180 //---------------------------------------------------------------------- | 251 //---------------------------------------------------------------------- |
| 181 | 252 |
| 182 } // namespace plugin; | 253 } // namespace plugin; |
| 183 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ | 254 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ |
| OLD | NEW |