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_sync_raii.h" | |
| 15 #include "native_client/src/shared/platform/nacl_threads.h" | 16 #include "native_client/src/shared/platform/nacl_threads.h" |
| 16 #include "native_client/src/shared/srpc/nacl_srpc.h" | 17 #include "native_client/src/shared/srpc/nacl_srpc.h" |
| 18 #include "native_client/src/trusted/desc/nacl_desc_rng.h" | |
| 17 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | 19 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
| 18 #include "native_client/src/trusted/plugin/delayed_callback.h" | 20 #include "native_client/src/trusted/plugin/delayed_callback.h" |
| 19 #include "native_client/src/trusted/plugin/nacl_subprocess.h" | 21 #include "native_client/src/trusted/plugin/nacl_subprocess.h" |
| 20 #include "native_client/src/trusted/plugin/plugin_error.h" | 22 #include "native_client/src/trusted/plugin/plugin_error.h" |
| 21 #include "native_client/src/trusted/plugin/pnacl_resources.h" | 23 #include "native_client/src/trusted/plugin/pnacl_resources.h" |
| 22 | 24 |
| 25 #include "ppapi/c/pp_file_info.h" | |
| 23 #include "ppapi/cpp/completion_callback.h" | 26 #include "ppapi/cpp/completion_callback.h" |
| 27 #include "ppapi/cpp/file_io.h" | |
| 28 #include "ppapi/cpp/file_ref.h" | |
| 29 #include "ppapi/cpp/file_system.h" | |
| 24 | 30 |
| 25 struct NaClMutex; | 31 struct NaClMutex; |
| 32 struct PPB_FileIOTrusted; | |
| 26 | 33 |
| 27 namespace plugin { | 34 namespace plugin { |
| 28 | 35 |
| 29 class Plugin; | 36 class Plugin; |
| 30 class PnaclCoordinator; | 37 class PnaclCoordinator; |
| 31 | 38 |
| 32 struct PnaclTranslationUnit { | 39 // Translation creates two temporary files. The first temporary file holds |
| 33 PnaclTranslationUnit(PnaclCoordinator* coord) | 40 // the object file created by llc. The second holds the nexe produced by |
| 34 : coordinator(coord), | 41 // the linker. Both of these temporary files are used to both write and |
| 35 obj_len(-1), | 42 // read according to the following matrix: |
| 36 is_shared_library(false), | 43 // |
| 37 soname(""), | 44 // PnaclCoordinator::obj_file_: |
| 38 lib_dependencies("") { | 45 // written by: llc (passed in explicitly through SRPC) |
| 46 // read by: ld (returned via lookup service from SRPC) | |
| 47 // PnaclCoordinator::nexe_file_: | |
| 48 // written by: lc (passed in explicitly through SRPC) | |
| 49 // read by: sel_ldr (passed in explicitly to command channel) | |
| 50 // | |
| 51 | |
| 52 // PnaclFileDescPair represents a file used as a temporary between stages in | |
| 53 // translation. It is created in the local temporary file system of the page | |
| 54 // being processed. The name of the temporary file is a random 32-character | |
| 55 // hex string. Because both reading and writing are necessary, two I/O objects | |
| 56 // for the file are opened. | |
| 57 class PnaclFileDescPair { | |
| 58 public: | |
| 59 PnaclFileDescPair(Plugin* plugin, | |
| 60 pp::FileSystem* file_system, | |
| 61 PnaclCoordinator* coordinator); | |
| 62 ~PnaclFileDescPair(); | |
| 63 // Opens a pair of file IO objects referring to a randomly named file in | |
| 64 // file_system_. One IO is for writing the file and another for reading it. | |
| 65 void Open(const pp::CompletionCallback& cb); | |
| 66 // Accessors. | |
| 67 // The nacl::DescWrapper* for the writeable version of the file. | |
| 68 nacl::DescWrapper* write_wrapper() { return write_wrapper_.get(); } | |
| 69 // The nacl::DescWrapper* for the read-only version of the file. | |
| 70 nacl::DescWrapper* read_wrapper() { return read_wrapper_.get(); } | |
| 71 | |
| 72 private: | |
| 73 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclFileDescPair); | |
| 74 | |
| 75 // Gets the POSIX file descriptor for a resource. | |
| 76 int32_t GetFD(int32_t pp_error, | |
| 77 const pp::Resource& resource, | |
| 78 bool is_writable); | |
| 79 // Called when the writable file IO was opened. | |
| 80 void WriteFileDidOpen(int32_t pp_error); | |
| 81 // Called when the readable file IO was opened. | |
| 82 void ReadFileDidOpen(int32_t pp_error); | |
| 83 | |
| 84 Plugin* plugin_; | |
| 85 pp::FileSystem* file_system_; | |
| 86 PnaclCoordinator* coordinator_; | |
| 87 const PPB_FileIOTrusted* file_io_trusted_; | |
| 88 pp::CompletionCallbackFactory<PnaclFileDescPair> callback_factory_; | |
| 89 nacl::string filename_; | |
| 90 // The PPAPI and wrapper state for the writeable file. | |
| 91 nacl::scoped_ptr<pp::FileRef> write_ref_; | |
| 92 nacl::scoped_ptr<pp::FileIO> write_io_; | |
| 93 nacl::scoped_ptr<nacl::DescWrapper> write_wrapper_; | |
| 94 // The PPAPI and wrapper state for the read-only file. | |
| 95 nacl::scoped_ptr<pp::FileRef> read_ref_; | |
| 96 nacl::scoped_ptr<pp::FileIO> read_io_; | |
| 97 nacl::scoped_ptr<nacl::DescWrapper> read_wrapper_; | |
| 98 // The callback invoked when both file I/O objects are created. | |
| 99 pp::CompletionCallback done_callback_; | |
| 100 // Random number generator used to create filenames. | |
| 101 struct NaClDescRng rng_desc_; | |
| 102 }; | |
| 103 | |
| 104 // A thread safe reference counting class Needed for CompletionCallbackFactory | |
| 105 // in PnaclCoordinator. | |
| 106 class PnaclRefCount { | |
| 107 public: | |
| 108 PnaclRefCount() : ref_(0) { NaClXMutexCtor(&mu_); } | |
| 109 ~PnaclRefCount() { NaClMutexDtor(&mu_); } | |
| 110 int32_t AddRef() { | |
| 111 nacl::MutexLocker ml(&mu_); | |
| 112 return ++ref_; | |
| 39 } | 113 } |
| 40 // Punch hole in abstraction. | 114 int32_t Release() { |
| 41 PnaclCoordinator* coordinator; | 115 nacl::MutexLocker ml(&mu_); |
| 42 | 116 return --ref_; |
| 43 // Borrowed reference which must outlive the thread. | 117 } |
| 44 nacl::scoped_ptr<nacl::DescWrapper> pexe_wrapper; | 118 |
| 45 | 119 private: |
| 46 // Object file produced by translator and consumed by the linker. | 120 int32_t ref_; |
| 47 nacl::scoped_ptr<nacl::DescWrapper> obj_wrapper; | 121 struct NaClMutex mu_; |
| 48 int32_t obj_len; | |
| 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. | |
| 59 pp::CompletionCallback translate_done_cb; | |
| 60 pp::CompletionCallback link_done_cb; | |
| 61 | |
| 62 ErrorInfo error_info; | |
| 63 }; | 122 }; |
| 64 | 123 |
| 65 | 124 // A class invoked by Plugin to handle PNaCl client-side translation. |
| 66 typedef std::pair<nacl::string, pp::CompletionCallback> url_callback_pair; | |
| 67 | |
| 68 // A class that handles PNaCl client-side translation. | |
| 69 // Usage: | 125 // Usage: |
| 70 // (1) Initialize(); | 126 // (1) Invoke the factory method, e.g., |
| 71 // (2) BitcodeToNative(bitcode, ..., finish_callback); | 127 // PnaclCoordinator* coord = BitcodeToNative(plugin, |
| 72 // (3) After finish_callback runs, do: | 128 // "http://foo.com/my.pexe", |
| 73 // fd = ReleaseTranslatedFD(); | 129 // TranslateNotifyCallback); |
| 74 // (4) go ahead and load the nexe from "fd" | 130 // (2) TranslateNotifyCallback gets invoked when translation is complete. |
| 75 // (5) delete | 131 // If the translation was successful, the pp_error argument is PP_OK. |
| 132 // Other values indicate errors. | |
| 133 // (3) After finish_callback runs, get the file descriptor of the translated | |
| 134 // nexe, e.g., | |
| 135 // fd = coord->ReleaseTranslatedFD(); | |
| 136 // (4) Load the nexe from "fd". | |
| 137 // (5) delete coord. | |
| 138 // | |
| 139 // Translation proceeds in two steps: | |
| 140 // (1) llc translates the bitcode in pexe_url_ to an object in obj_file_. | |
| 141 // (2) ld links the object code in obj_file_ and produces a nexe in nexe_file_. | |
| 142 // | |
| 143 // It should be noted that at the moment we are not properly freeing the | |
| 144 // PPAPI resources used for the temporary files used in translation. Until | |
| 145 // that is fixed, (4) and (5) should be done in that order. | |
| 146 // TODO(sehr): Fix freeing of temporary files. | |
| 76 class PnaclCoordinator { | 147 class PnaclCoordinator { |
| 77 public: | 148 public: |
| 78 PnaclCoordinator() | |
| 79 : plugin_(NULL), | |
| 80 translate_notify_callback_(pp::BlockUntilComplete()), | |
| 81 llc_subprocess_(NULL), | |
| 82 ld_subprocess_(NULL), | |
| 83 subprocesses_should_die_(false) { | |
| 84 NaClXMutexCtor(&subprocess_mu_); | |
| 85 } | |
| 86 | |
| 87 virtual ~PnaclCoordinator(); | 149 virtual ~PnaclCoordinator(); |
| 88 | 150 |
| 89 // Initialize() can only be called once during the lifetime of this instance. | 151 // The factory method for translations. |
| 90 void Initialize(Plugin* instance); | 152 static PnaclCoordinator* BitcodeToNative( |
| 91 | 153 Plugin* plugin, |
| 92 void BitcodeToNative(const nacl::string& pexe_url, | 154 const nacl::string& pexe_url, |
| 93 const pp::CompletionCallback& finish_callback); | 155 const pp::CompletionCallback& translate_notify_callback); |
| 94 | 156 |
| 95 // Call this to take ownership of the FD of the translated nexe after | 157 // Call this to take ownership of the FD of the translated nexe after |
| 96 // BitcodeToNative has completed (and the finish_callback called). | 158 // BitcodeToNative has completed (and the finish_callback called). |
| 97 nacl::DescWrapper* ReleaseTranslatedFD() { | 159 nacl::DescWrapper* ReleaseTranslatedFD() { return translated_fd_.release(); } |
| 98 return translated_fd_.release(); | 160 |
| 99 } | 161 // Looks up a file descriptor for an url that was already downloaded. |
| 100 | 162 // This is used for getting the descriptor for llc and ld nexes as well |
| 163 // as the libraries and object files used by the linker. | |
| 101 int32_t GetLoadedFileDesc(int32_t pp_error, | 164 int32_t GetLoadedFileDesc(int32_t pp_error, |
| 102 const nacl::string& url, | 165 const nacl::string& url, |
| 103 const nacl::string& component); | 166 const nacl::string& component); |
| 104 | 167 |
| 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 | 168 // Run |translate_notify_callback_| with an error condition that is not |
| 109 // PPAPI specific. | 169 // PPAPI specific. |
| 110 void PnaclNonPpapiError(); | 170 void ReportNonPpapiError(const nacl::string& message); |
| 111 // Wrapper for Plugin ReportLoadAbort. | 171 // Run when faced with a PPAPI error condition. Bring control back to the |
| 112 void ReportLoadAbort(); | 172 // plugin by invoking the |translate_notify_callback_|. |
| 113 // Wrapper for Plugin ReportLoadError. | 173 void ReportPpapiError(int32_t pp_error, const nacl::string& message); |
| 114 void ReportLoadError(const ErrorInfo& error); | 174 void ReportPpapiError(int32_t pp_error); |
| 115 | |
| 116 // Accessors for use by helper threads. | |
| 117 nacl::string resource_base_url() const { return resource_base_url_; } | |
| 118 Plugin* plugin() const { return plugin_; } | |
| 119 nacl::string llc_url() const { return llc_url_; } | |
| 120 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_; } | |
| 124 bool StartLdSubProcess(); | |
| 125 bool SubprocessesShouldDie(); | |
| 126 void SetSubprocessesShouldDie(bool subprocesses_should_die); | |
| 127 PnaclResources* resources() const { return resources_.get(); } | |
| 128 | |
| 129 protected: | |
| 130 | |
| 131 // Callbacks for when various files, etc. have been downloaded. | |
| 132 void ResourcesDidLoad(int32_t pp_error, | |
| 133 const nacl::string& url, | |
| 134 PnaclTranslationUnit* translation_unit); | |
| 135 | |
| 136 // Callbacks for compute-based translation steps. | |
| 137 void RunTranslate(int32_t pp_error, | |
| 138 const nacl::string& url, | |
| 139 PnaclTranslationUnit* translation_unit); | |
| 140 void RunLink(int32_t pp_error, PnaclTranslationUnit* translation_unit); | |
| 141 | |
| 142 // Pnacl translation completed normally. | |
| 143 void PnaclDidFinish(int32_t pp_error, PnaclTranslationUnit* translation_unit); | |
| 144 | 175 |
| 145 private: | 176 private: |
| 146 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator); | 177 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator); |
| 147 | 178 |
| 179 // BitcodeToNative is the factory method for PnaclCoordinators. | |
| 180 // Therefore the constructor is private. | |
| 181 PnaclCoordinator(Plugin* plugin, | |
| 182 const nacl::string& pexe_url, | |
| 183 const pp::CompletionCallback& translate_notify_callback, | |
| 184 const nacl::string& resource_base_url); | |
| 185 | |
| 186 // Callback for when llc and ld have been downloaded. | |
| 187 // This is the first callback invoked in response to BitcodeToNative. | |
| 188 void ResourcesDidLoad(int32_t pp_error); | |
| 189 | |
| 190 // Callbacks for temporary file related stages. | |
| 191 // They are invoked from ResourcesDidLoad and proceed in declaration order. | |
| 192 // Invoked when the temporary file system is successfully opened in PPAPI. | |
| 193 void FileSystemDidOpen(int32_t pp_error); | |
| 194 // Invoked when the obj_file_ temporary file I/O pair is created. | |
| 195 void ObjectPairDidOpen(int32_t pp_error); | |
| 196 // Invoked when the nexe_file_ temporary file I/O pair is created. | |
| 197 void NexePairDidOpen(int32_t pp_error); | |
| 198 | |
| 199 // Once llc and ld nexes have been loaded and the two temporary files have | |
| 200 // been created, this starts the translation. Translation starts two | |
| 201 // subprocesses, one for llc and one for ld. | |
| 202 void RunTranslate(int32_t pp_error); | |
| 203 // Starts an individual llc or ld subprocess used for translation. | |
| 204 NaClSubprocess* StartSubprocess(const nacl::string& url); | |
| 205 // PnaclCoordinator creates a helper thread to allow translations to be | |
| 206 // invoked via SRPC. This is the helper thread function for translation. | |
| 207 static void WINAPI DoTranslateThread(void* arg); | |
| 208 // Returns true if a the translate thread and subprocesses should stop. | |
| 209 bool SubprocessesShouldDie(); | |
| 210 // Signal the translate thread and subprocesses that they should stop. | |
| 211 void SetSubprocessesShouldDie(bool subprocesses_should_die); | |
| 212 // Signal that Pnacl translation completed normally. | |
| 213 void PnaclDidFinish(int32_t pp_error); | |
| 214 // Signal that Pnacl translation failed. | |
|
jvoung - send to chromium...
2011/12/13 21:35:49
"from the translation thread" only?
sehr (please use chromium)
2011/12/14 16:34:20
Done.
| |
| 215 void PnaclFailed(const nacl::string& error_string); | |
| 216 | |
| 217 // Support for file lookups needed for ld. | |
| 218 // TODO(sehr): remove this when file lookup is through ReverseService. | |
| 219 // Invoked on the main thread on behalf of the lookup service to start | |
| 220 // loading a particular URL. | |
| 221 void LoadOneFile(int32_t pp_error, | |
| 222 const nacl::string& url, | |
| 223 nacl::DescWrapper** wrapper, | |
| 224 pp::CompletionCallback& done_cb); | |
| 225 // Invoked by the renderer when the file was loaded. | |
| 226 void DidLoadFile(int32_t pp_error, | |
| 227 const nacl::string& full_url, | |
| 228 nacl::DescWrapper** wrapper, | |
| 229 pp::CompletionCallback& done_cb); | |
| 230 // Signals the waiting lookup service to resume. | |
| 231 void ResumeLookup(int32_t pp_error); | |
| 232 | |
| 233 // The plugin owning the nexe for which we are doing translation. | |
| 148 Plugin* plugin_; | 234 Plugin* plugin_; |
| 235 | |
| 149 pp::CompletionCallback translate_notify_callback_; | 236 pp::CompletionCallback translate_notify_callback_; |
| 150 pp::CompletionCallbackFactory<PnaclCoordinator> callback_factory_; | 237 // PnaclRefCount is only needed to support file lookups. |
| 238 // TODO(sehr): remove this when file lookup is through ReverseService. | |
| 239 pp::CompletionCallbackFactory<PnaclCoordinator, | |
| 240 PnaclRefCount> callback_factory_; | |
| 151 | 241 |
| 152 // URLs used to lookup downloaded resources. | 242 // URLs used to lookup downloaded resources. |
| 153 nacl::string resource_base_url_; | 243 nacl::string resource_base_url_; |
| 154 nacl::string llc_url_; | |
| 155 nacl::string ld_url_; | |
| 156 | 244 |
| 157 // Helper subprocesses loaded by the plugin (deleted by the plugin). | 245 // Helper subprocesses loaded by the plugin (deleted by the plugin). |
| 158 // We may want to do cleanup ourselves when we are in the | 246 // A nacl sandbox running the llc nexe. |
| 159 // business of compiling multiple bitcode objects / libraries, and | |
| 160 // if we truly cannot reuse existing loaded subprocesses. | |
| 161 NaClSubprocess* llc_subprocess_; | 247 NaClSubprocess* llc_subprocess_; |
| 248 // A nacl sandbox running the ld nexe. | |
| 162 NaClSubprocess* ld_subprocess_; | 249 NaClSubprocess* ld_subprocess_; |
| 250 // True if the translation thread and subprocesses should exit. | |
| 163 bool subprocesses_should_die_; | 251 bool subprocesses_should_die_; |
| 252 // Used to guard and publish subprocesses_should_die_. | |
| 164 struct NaClMutex subprocess_mu_; | 253 struct NaClMutex subprocess_mu_; |
| 165 | 254 |
| 166 // Nexe from the final native Link. | 255 // Nexe from the final native Link. |
| 167 nacl::scoped_ptr<nacl::DescWrapper> translated_fd_; | 256 nacl::scoped_ptr<nacl::DescWrapper> translated_fd_; |
| 168 | 257 |
| 169 // Perhaps make this a single thread that invokes (S)RPCs followed by | 258 // The helper thread used to do translations via SRPC. |
| 170 // 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?). | |
| 172 nacl::scoped_ptr<PnaclTranslationUnit> translation_unit_; | |
| 173 nacl::scoped_ptr<NaClThread> translate_thread_; | 259 nacl::scoped_ptr<NaClThread> translate_thread_; |
| 174 nacl::scoped_ptr<NaClThread> link_thread_; | 260 // Translation creates local temporary files. |
| 175 | 261 nacl::scoped_ptr<pp::FileSystem> file_system_; |
| 176 // An auxiliary class that manages downloaded resources. | 262 // An auxiliary class that manages downloaded resources (llc and ld nexes). |
| 177 nacl::scoped_ptr<PnaclResources> resources_; | 263 nacl::scoped_ptr<PnaclResources> resources_; |
| 264 | |
| 265 // The URL for the pexe file. | |
| 266 nacl::string pexe_url_; | |
| 267 // Borrowed reference which must outlive the thread. | |
| 268 nacl::scoped_ptr<nacl::DescWrapper> pexe_wrapper_; | |
| 269 // Object file, produced by the translator and consumed by the linker. | |
| 270 nacl::scoped_ptr<PnaclFileDescPair> obj_file_; | |
| 271 // Translated nexe file, produced by the linker and consumed by sel_ldr. | |
| 272 nacl::scoped_ptr<PnaclFileDescPair> nexe_file_; | |
| 273 // Callbacks to run when tasks or completed or an error has occurred. | |
| 274 pp::CompletionCallback translate_done_cb_; | |
| 275 | |
| 276 // Used to report information when errors (PPAPI or otherwise) are reported. | |
| 277 ErrorInfo error_info_; | |
| 278 | |
| 279 // Support for file lookups (obsolescent). | |
| 280 // The SRPC file lookup service for ld. | |
| 281 static void LookupInputFile(NaClSrpcRpc* rpc, | |
| 282 NaClSrpcArg** inputs, | |
| 283 NaClSrpcArg** outputs, | |
| 284 NaClSrpcClosure* done); | |
| 285 static NaClSrpcHandlerDesc lookup_methods[]; | |
| 286 | |
| 287 // Used by the SRPC file lookup service for ld. | |
| 288 // Looks up url and returns the read-only file descriptor for it. | |
| 289 // If url is the specially designated filename for the translated object | |
| 290 // file, it returns obj_file_.read_wrapper(). Otherwise the lookup causes | |
| 291 // the download of the requested resource via Plugin::StreamAsFile. | |
| 292 struct NaClDesc* LookupDesc(const nacl::string& url); | |
| 293 | |
| 294 struct NaClMutex lookup_service_mu_; | |
| 295 struct NaClCondVar lookup_service_cv_; | |
| 296 bool lookup_is_complete_; | |
| 178 }; | 297 }; |
| 179 | 298 |
| 180 //---------------------------------------------------------------------- | 299 //---------------------------------------------------------------------- |
| 181 | 300 |
| 182 } // namespace plugin; | 301 } // namespace plugin; |
| 183 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ | 302 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_COORDINATOR_H_ |
| OLD | NEW |