diff options
author | teravest@chromium.org <teravest@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-22 15:54:45 +0000 |
---|---|---|
committer | teravest@chromium.org <teravest@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-22 15:54:45 +0000 |
commit | 262509a82256d68cf728cbd6f0a9f4c80888250f (patch) | |
tree | 49d32e27a1c0c72689b376aee73687a08c1cc7c1 /ppapi/native_client | |
parent | e13c91421aac9bfc656106ccc284f7c940284fac (diff) | |
download | chromium_src-262509a82256d68cf728cbd6f0a9f4c80888250f.zip chromium_src-262509a82256d68cf728cbd6f0a9f4c80888250f.tar.gz chromium_src-262509a82256d68cf728cbd6f0a9f4c80888250f.tar.bz2 |
Pepper: Delete FileDownloader in trusted plugin.
This simplifies PnaclCoordinator considerably and reduces the total
amount of code in the trusted plugin.
BUG=239656
Review URL: https://codereview.chromium.org/393693004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284684 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/native_client')
10 files changed, 123 insertions, 530 deletions
diff --git a/ppapi/native_client/src/trusted/plugin/callback_source.h b/ppapi/native_client/src/trusted/plugin/callback_source.h deleted file mode 100644 index 928a577..0000000 --- a/ppapi/native_client/src/trusted/plugin/callback_source.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_CALLBACK_SOURCE_H -#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_CALLBACK_SOURCE_H - -#include "ppapi/cpp/completion_callback.h" - -namespace plugin { - -// Classes that implement this interface can be used with FileDownloader's -// DOWNLOAD_STREAM mode. For each chunk of the file as it downloads, -// The FileDownloader will get a callback of type -// pp::CompletionCallbackWithOutput<std::vector<char>*> using the -// GetCallback function, and call it immediately, passing a pointer to a -// vector with the data as the output field. The class is templatized just -// in case there are any other use cases in the future. -// This class really only exists as a way to get callbacks -// bound to an object (i.e. we don't need the asynchronous behavior of PPAPI) -// All we really need is tr1::function or base::bind or some such, but we don't -// have those in the plugin. - -template<class T> -class CallbackSource { - public: - virtual ~CallbackSource(); - // Returns a callback from callback_factory's NewCallbackWithOutput, - // bound to the implementing object. - virtual pp::CompletionCallbackWithOutput<T> GetCallback() = 0; -}; -} -#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_CALLBACK_SOURCE_H diff --git a/ppapi/native_client/src/trusted/plugin/file_downloader.cc b/ppapi/native_client/src/trusted/plugin/file_downloader.cc deleted file mode 100644 index ccddfe8..0000000 --- a/ppapi/native_client/src/trusted/plugin/file_downloader.cc +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ppapi/native_client/src/trusted/plugin/file_downloader.h" - -#include <stdio.h> -#include <string.h> -#include <string> - -#include "native_client/src/include/portability_io.h" -#include "native_client/src/shared/platform/nacl_check.h" -#include "native_client/src/shared/platform/nacl_time.h" -#include "ppapi/c/pp_errors.h" -#include "ppapi/cpp/url_request_info.h" -#include "ppapi/cpp/url_response_info.h" -#include "ppapi/native_client/src/trusted/plugin/callback_source.h" -#include "ppapi/native_client/src/trusted/plugin/plugin.h" -#include "ppapi/native_client/src/trusted/plugin/utility.h" - -namespace plugin { - -FileDownloader::FileDownloader(Plugin* instance) - : instance_(instance), - file_open_notify_callback_(pp::BlockUntilComplete()), - stream_finish_callback_(pp::BlockUntilComplete()), - mode_(DOWNLOAD_NONE), - data_stream_callback_source_(NULL) { - callback_factory_.Initialize(this); - temp_buffer_.resize(kTempBufferSize); -} - -bool FileDownloader::OpenStream( - const nacl::string& url, - const pp::CompletionCallback& callback, - StreamCallbackSource* stream_callback_source) { - data_stream_callback_source_ = stream_callback_source; - PLUGIN_PRINTF(("FileDownloader::Open (url=%s)\n", url.c_str())); - if (callback.pp_completion_callback().func == NULL || instance_ == NULL) - return false; - - status_code_ = -1; - file_open_notify_callback_ = callback; - mode_ = DOWNLOAD_TO_BUFFER_AND_STREAM; - pp::URLRequestInfo url_request(instance_); - - // Allow CORS. - // Note that "SetAllowCrossOriginRequests" (currently) has the side effect of - // preventing credentials from being sent on same-origin requests. We - // therefore avoid setting this flag unless we know for sure it is a - // cross-origin request, resulting in behavior similar to XMLHttpRequest. - if (!instance_->DocumentCanRequest(url)) - url_request.SetAllowCrossOriginRequests(true); - - if (!extra_request_headers_.empty()) - url_request.SetHeaders(extra_request_headers_); - - // Reset the url loader and file reader. - // Note that we have the only reference to the underlying objects, so - // this will implicitly close any pending IO and destroy them. - url_loader_ = pp::URLLoader(instance_); - url_request.SetRecordDownloadProgress(true); - - // Prepare the url request. - url_request.SetURL(url); - - // Request asynchronous download of the url providing an on-load callback. - // As long as this step is guaranteed to be asynchronous, we can call - // synchronously all other internal callbacks that eventually result in the - // invocation of the user callback. The user code will not be reentered. - pp::CompletionCallback onload_callback = - callback_factory_.NewCallback(&FileDownloader::URLLoadStartNotify); - int32_t pp_error = url_loader_.Open(url_request, onload_callback); - PLUGIN_PRINTF(("FileDownloader::Open (pp_error=%" NACL_PRId32 ")\n", - pp_error)); - CHECK(pp_error == PP_OK_COMPLETIONPENDING); - return true; -} - -bool FileDownloader::InitialResponseIsValid() { - // Process the response, validating the headers to confirm successful loading. - url_response_ = url_loader_.GetResponseInfo(); - if (url_response_.is_null()) { - PLUGIN_PRINTF(( - "FileDownloader::InitialResponseIsValid (url_response_=NULL)\n")); - return false; - } - - pp::Var full_url = url_response_.GetURL(); - if (!full_url.is_string()) { - PLUGIN_PRINTF(( - "FileDownloader::InitialResponseIsValid (url is not a string)\n")); - return false; - } - full_url_ = full_url.AsString(); - - status_code_ = url_response_.GetStatusCode(); - PLUGIN_PRINTF(("FileDownloader::InitialResponseIsValid (" - "response status_code=%" NACL_PRId32 ")\n", status_code_)); - return status_code_ == NACL_HTTP_STATUS_OK; -} - -void FileDownloader::URLLoadStartNotify(int32_t pp_error) { - PLUGIN_PRINTF(("FileDownloader::URLLoadStartNotify (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error != PP_OK) { - file_open_notify_callback_.RunAndClear(pp_error); - return; - } - - if (!InitialResponseIsValid()) { - file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED); - return; - } - - file_open_notify_callback_.RunAndClear(PP_OK); -} - -void FileDownloader::BeginStreaming( - const pp::CompletionCallback& callback) { - stream_finish_callback_ = callback; - - // Finish streaming the body providing an optional callback. - pp::CompletionCallback onread_callback = - callback_factory_.NewOptionalCallback( - &FileDownloader::URLReadBodyNotify); - int32_t temp_size = static_cast<int32_t>(temp_buffer_.size()); - int32_t pp_error = url_loader_.ReadResponseBody(&temp_buffer_[0], - temp_size, - onread_callback); - if (pp_error != PP_OK_COMPLETIONPENDING) - onread_callback.RunAndClear(pp_error); -} - -void FileDownloader::URLReadBodyNotify(int32_t pp_error) { - PLUGIN_PRINTF(("FileDownloader::URLReadBodyNotify (pp_error=%" - NACL_PRId32")\n", pp_error)); - if (pp_error < PP_OK) { - stream_finish_callback_.RunAndClear(pp_error); - } else if (pp_error == PP_OK) { - data_stream_callback_source_->GetCallback().RunAndClear(PP_OK); - stream_finish_callback_.RunAndClear(PP_OK); - } else { - PLUGIN_PRINTF(("Running data_stream_callback, temp_buffer_=%p\n", - &temp_buffer_[0])); - StreamCallback cb = data_stream_callback_source_->GetCallback(); - *(cb.output()) = &temp_buffer_; - cb.RunAndClear(pp_error); - - pp::CompletionCallback onread_callback = - callback_factory_.NewOptionalCallback( - &FileDownloader::URLReadBodyNotify); - int32_t temp_size = static_cast<int32_t>(temp_buffer_.size()); - pp_error = url_loader_.ReadResponseBody(&temp_buffer_[0], - temp_size, - onread_callback); - if (pp_error != PP_OK_COMPLETIONPENDING) - onread_callback.RunAndClear(pp_error); - } -} - -bool FileDownloader::GetDownloadProgress( - int64_t* bytes_received, - int64_t* total_bytes_to_be_received) const { - return url_loader_.GetDownloadProgress(bytes_received, - total_bytes_to_be_received); -} - -nacl::string FileDownloader::GetResponseHeaders() const { - pp::Var headers = url_response_.GetHeaders(); - if (!headers.is_string()) { - PLUGIN_PRINTF(( - "FileDownloader::GetResponseHeaders (headers are not a string)\n")); - return nacl::string(); - } - return headers.AsString(); -} - -} // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/file_downloader.h b/ppapi/native_client/src/trusted/plugin/file_downloader.h deleted file mode 100644 index 4a1a71a..0000000 --- a/ppapi/native_client/src/trusted/plugin/file_downloader.h +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ -#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ - -#include <deque> - -#include "native_client/src/include/nacl_macros.h" -#include "native_client/src/include/nacl_string.h" -#include "native_client/src/public/nacl_file_info.h" -#include "ppapi/c/private/ppb_nacl_private.h" -#include "ppapi/cpp/file_io.h" -#include "ppapi/cpp/instance.h" -#include "ppapi/cpp/url_loader.h" -#include "ppapi/cpp/url_response_info.h" -#include "ppapi/native_client/src/trusted/plugin/callback_source.h" -#include "ppapi/utility/completion_callback_factory.h" - -namespace plugin { - -class Plugin; - -typedef enum { - DOWNLOAD_TO_BUFFER_AND_STREAM = 0, - DOWNLOAD_NONE -} DownloadMode; - -typedef std::vector<char>* FileStreamData; -typedef CallbackSource<FileStreamData> StreamCallbackSource; -typedef pp::CompletionCallbackWithOutput<FileStreamData> StreamCallback; - -// A class that wraps PPAPI URLLoader and FileIO functionality for downloading -// the url into a file and providing an open file descriptor. -class FileDownloader { - public: - explicit FileDownloader(Plugin* instance); - ~FileDownloader() {} - - // Issues a GET on |url| to start downloading the response into a file, - // and finish streaming it. |callback| will be run after streaming is - // done or if an error prevents streaming from completing. - // Returns true when callback is scheduled to be called on success or failure. - // Returns false if callback is NULL, or if the PPB_FileIO_Trusted interface - // is not available. - // If |record_progress| is true, then download progress will be recorded, - // and can be polled through GetDownloadProgress(). - // If |progress_callback| is not NULL and |record_progress| is true, - // then the callback will be invoked for every progress update received - // by the loader. - - // Similar to Open(), but used for streaming the |url| data directly to the - // caller without writing to a temporary file. The callbacks provided by - // |stream_callback_source| are expected to copy the data before returning. - // |callback| is called once the response headers are received, - // and streaming must be completed separately via BeginStreaming(). - bool OpenStream(const nacl::string& url, - const pp::CompletionCallback& callback, - StreamCallbackSource* stream_callback_source); - - // Finish streaming the response body for a URL request started by either - // OpenStream(). Runs the given |callback| when streaming is done. - void BeginStreaming(const pp::CompletionCallback& callback); - - // Once the GET request has finished, and the contents of the file - // represented by |url_| are available, |full_url_| is the full URL including - // the scheme, host and full path. - // Returns an empty string before the GET request has finished. - const nacl::string& full_url() const { return full_url_; } - - // GetDownloadProgress() returns the current download progress, which is - // meaningful after Open() has been called. Progress only refers to the - // response body and does not include the headers. - // - // This data is only available if the |record_progress| true in the - // Open() call. If progress is being recorded, then |bytes_received| - // will be set to the number of bytes received thus far, - // and |total_bytes_to_be_received| will be set to the total number - // of bytes to be received. The total bytes to be received may be unknown, - // in which case |total_bytes_to_be_received| will be set to -1. - bool GetDownloadProgress(int64_t* bytes_received, - int64_t* total_bytes_to_be_received) const; - - int status_code() const { return status_code_; } - nacl::string GetResponseHeaders() const; - - void set_request_headers(const nacl::string& extra_request_headers) { - extra_request_headers_ = extra_request_headers; - } - - private: - NACL_DISALLOW_COPY_AND_ASSIGN(FileDownloader); - - // For DOWNLOAD_TO_BUFFER_AND_STREAM, the process is very similar: - // 1) Ask the browser to start streaming |url_| to an internal buffer. - // 2) Ask the browser to finish streaming to |temp_buffer_| on success. - // 3) Wait for streaming to finish, passing the data directly to the user. - // Each step is done asynchronously using callbacks. We create callbacks - // through a factory to take advantage of ref-counting. - // The public Open*() functions start step 1), and the public BeginStreaming - // function proceeds to step 2) and 3). - bool InitialResponseIsValid(); - void URLLoadStartNotify(int32_t pp_error); - void URLReadBodyNotify(int32_t pp_error); - - Plugin* instance_; - nacl::string full_url_; - - nacl::string extra_request_headers_; - pp::URLResponseInfo url_response_; - pp::CompletionCallback file_open_notify_callback_; - pp::CompletionCallback stream_finish_callback_; - pp::URLLoader url_loader_; - pp::CompletionCallbackFactory<FileDownloader> callback_factory_; - int32_t status_code_; - DownloadMode mode_; - static const uint32_t kTempBufferSize = 16384; - std::vector<char> temp_buffer_; - StreamCallbackSource* data_stream_callback_source_; -}; - -} // namespace plugin - -#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gypi b/ppapi/native_client/src/trusted/plugin/plugin.gypi index 38bcd5c..a29fac1 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.gypi +++ b/ppapi/native_client/src/trusted/plugin/plugin.gypi @@ -6,7 +6,6 @@ 'variables': { 'chromium_code': 1, # Use higher warning level. 'common_sources': [ - 'file_downloader.cc', 'module_ppapi.cc', 'nacl_subprocess.cc', 'plugin.cc', diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h index 29409c4..721018c 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.h +++ b/ppapi/native_client/src/trusted/plugin/plugin.h @@ -28,12 +28,13 @@ #include "ppapi/cpp/var.h" #include "ppapi/cpp/view.h" -#include "ppapi/native_client/src/trusted/plugin/file_downloader.h" #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h" #include "ppapi/native_client/src/trusted/plugin/service_runtime.h" #include "ppapi/native_client/src/trusted/plugin/utility.h" +#include "ppapi/utility/completion_callback_factory.h" + namespace nacl { class DescWrapper; class DescWrapperFactory; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index 3669159..6ce3646 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -63,12 +63,34 @@ nacl::string GetArchitectureAttributes(Plugin* plugin) { return attrs_var.AsString(); } -} // namespace +void DidCacheHit(void* user_data, PP_FileHandle nexe_file_handle) { + PnaclCoordinator* coordinator = static_cast<PnaclCoordinator*>(user_data); + coordinator->BitcodeStreamCacheHit(nexe_file_handle); +} + +void DidCacheMiss(void* user_data, int64_t expected_pexe_size) { + PnaclCoordinator* coordinator = static_cast<PnaclCoordinator*>(user_data); + coordinator->BitcodeStreamCacheMiss(expected_pexe_size); +} + +void DidStreamData(void* user_data, const void* stream_data, int32_t length) { + PnaclCoordinator* coordinator = static_cast<PnaclCoordinator*>(user_data); + coordinator->BitcodeStreamGotData(stream_data, length); +} + +void DidFinishStream(void* user_data, int32_t pp_error) { + PnaclCoordinator* coordinator = static_cast<PnaclCoordinator*>(user_data); + coordinator->BitcodeStreamDidFinish(pp_error); +} + +PPP_PexeStreamHandler kPexeStreamHandler = { + &DidCacheHit, + &DidCacheMiss, + &DidStreamData, + &DidFinishStream +}; -// Out-of-line destructor to keep it from getting put in every .o where -// callback_source.h is included -template<> -CallbackSource<FileStreamData>::~CallbackSource() {} +} // namespace PnaclCoordinator* PnaclCoordinator::BitcodeToNative( Plugin* plugin, @@ -107,7 +129,6 @@ PnaclCoordinator::PnaclCoordinator( pnacl_options_(pnacl_options), architecture_attributes_(GetArchitectureAttributes(plugin)), split_module_count_(1), - is_cache_hit_(PP_FALSE), error_already_reported_(false), pexe_size_(0), pexe_bytes_compiled_(0), @@ -265,44 +286,6 @@ void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { } void PnaclCoordinator::OpenBitcodeStream() { - // Now open the pexe stream. - streaming_downloader_.reset(new FileDownloader(plugin_)); - // Mark the request as requesting a PNaCl bitcode file, - // so that component updater can detect this user action. - streaming_downloader_->set_request_headers( - "Accept: application/x-pnacl, */*"); - - // Even though we haven't started downloading, create the translation - // thread object immediately. This ensures that any pieces of the file - // that get downloaded before the compilation thread is accepting - // SRPCs won't get dropped. - translate_thread_.reset(new PnaclTranslateThread()); - if (translate_thread_ == NULL) { - ReportNonPpapiError( - PP_NACL_ERROR_PNACL_THREAD_CREATE, - "PnaclCoordinator: could not allocate translation thread."); - return; - } - - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::BitcodeStreamDidOpen); - if (!streaming_downloader_->OpenStream(pexe_url_, cb, this)) { - ReportNonPpapiError( - PP_NACL_ERROR_PNACL_PEXE_FETCH_OTHER, - nacl::string("PnaclCoordinator: failed to open stream ") + pexe_url_); - return; - } -} - -void PnaclCoordinator::BitcodeStreamDidOpen(int32_t pp_error) { - if (pp_error != PP_OK) { - BitcodeStreamDidFinish(pp_error); - // We have not spun up the translation process yet, so we need to call - // TranslateFinished here. - TranslateFinished(pp_error); - return; - } - // The component updater's resource throttles + OnDemand update/install // should block the URL request until the compiler is present. Now we // can load the resources (e.g. llc and ld nexes). @@ -326,87 +309,73 @@ void PnaclCoordinator::BitcodeStreamDidOpen(int32_t pp_error) { return; } - // Okay, now that we've started the HTTP request for the pexe - // and we've ensured that the PNaCl compiler + metadata is installed, - // get the cache key from the response headers and from the - // compiler's version metadata. - nacl::string headers = streaming_downloader_->GetResponseHeaders(); - - temp_nexe_file_.reset(new TempFile(plugin_)); - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::NexeFdDidOpen); - int32_t nexe_fd_err = - plugin_->nacl_interface()->GetNexeFd( - plugin_->pp_instance(), - streaming_downloader_->full_url().c_str(), - // TODO(dschuff): Get this value from the pnacl json file after it - // rolls in from NaCl. - 1, - pnacl_options_.opt_level, - headers.c_str(), - architecture_attributes_.c_str(), // Extra compile flags. - &is_cache_hit_, - temp_nexe_file_->internal_handle(), - cb.pp_completion_callback()); - if (nexe_fd_err < PP_OK_COMPLETIONPENDING) { - ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, nexe_fd_err, - nacl::string("Call to GetNexeFd failed")); - } -} - -void PnaclCoordinator::NexeFdDidOpen(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::NexeFdDidOpen (pp_error=%" - NACL_PRId32 ", hit=%d)\n", pp_error, - is_cache_hit_ == PP_TRUE)); - if (pp_error < PP_OK) { - ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, pp_error, - nacl::string("GetNexeFd failed")); + // Even though we haven't started downloading, create the translation + // thread object immediately. This ensures that any pieces of the file + // that get downloaded before the compilation thread is accepting + // SRPCs won't get dropped. + translate_thread_.reset(new PnaclTranslateThread()); + if (translate_thread_ == NULL) { + ReportNonPpapiError( + PP_NACL_ERROR_PNACL_THREAD_CREATE, + "PnaclCoordinator: could not allocate translation thread."); return; } - if (*temp_nexe_file_->internal_handle() == PP_kInvalidFileHandle) { + GetNaClInterface()->StreamPexe(plugin_->pp_instance(), + pexe_url_.c_str(), + pnacl_options_.opt_level, + &kPexeStreamHandler, + this); +} + +void PnaclCoordinator::BitcodeStreamCacheHit(PP_FileHandle handle) { + HistogramEnumerateTranslationCache(plugin_->uma_interface(), true); + if (handle == PP_kInvalidFileHandle) { ReportNonPpapiError( PP_NACL_ERROR_PNACL_CREATE_TEMP, nacl::string( "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); + BitcodeStreamDidFinish(PP_ERROR_FAILED); return; } - HistogramEnumerateTranslationCache(plugin_->uma_interface(), is_cache_hit_); + *temp_nexe_file_->internal_handle() = handle; + // Open it for reading as the cached nexe file. + NexeReadDidOpen(temp_nexe_file_->Open(false)); +} - if (is_cache_hit_ == PP_TRUE) { - // Cache hit -- no need to stream the rest of the file. - streaming_downloader_.reset(NULL); - // Open it for reading as the cached nexe file. - NexeReadDidOpen(temp_nexe_file_->Open(false)); - } else { - // Open an object file first so the translator can start writing to it - // during streaming translation. - for (int i = 0; i < split_module_count_; i++) { - nacl::scoped_ptr<TempFile> temp_file(new TempFile(plugin_)); - int32_t pp_error = temp_file->Open(true); - if (pp_error != PP_OK) { - ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, - pp_error, - "Failed to open scratch object file."); - return; - } else { - obj_files_.push_back(temp_file.release()); - } +void PnaclCoordinator::BitcodeStreamCacheMiss(int64_t expected_pexe_size) { + HistogramEnumerateTranslationCache(plugin_->uma_interface(), false); + expected_pexe_size_ = expected_pexe_size; + + // Open an object file first so the translator can start writing to it + // during streaming translation. + temp_nexe_file_.reset(new TempFile(plugin_)); + + for (int i = 0; i < split_module_count_; i++) { + nacl::scoped_ptr<TempFile> temp_file(new TempFile(plugin_)); + int32_t pp_error = temp_file->Open(true); + if (pp_error != PP_OK) { + ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, + pp_error, + "Failed to open scratch object file."); + return; + } else { + obj_files_.push_back(temp_file.release()); } - invalid_desc_wrapper_.reset(plugin_->wrapper_factory()->MakeInvalid()); - - // Meanwhile, a miss means we know we need to stream the bitcode, so stream - // the rest of it now. (Calling BeginStreaming means that the downloader - // will begin handing data to the coordinator, which is safe any time after - // the translate_thread_ object has been initialized). - pp::CompletionCallback finish_cb = callback_factory_.NewCallback( - &PnaclCoordinator::BitcodeStreamDidFinish); - streaming_downloader_->BeginStreaming(finish_cb); - - // Open the nexe file for connecting ld and sel_ldr. - // Start translation when done with this last step of setup! - RunTranslate(temp_nexe_file_->Open(true)); } + invalid_desc_wrapper_.reset(plugin_->wrapper_factory()->MakeInvalid()); + + // Open the nexe file for connecting ld and sel_ldr. + // Start translation when done with this last step of setup! + RunTranslate(temp_nexe_file_->Open(true)); +} + +void PnaclCoordinator::BitcodeStreamGotData(const void* data, int32_t length) { + DCHECK(translate_thread_.get()); + + translate_thread_->PutBytes(data, length); + if (data && length > 0) + pexe_size_ += length; } void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { @@ -429,47 +398,24 @@ void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ")."; error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); } - translate_thread_->AbortSubprocesses(); + + if (translate_thread_->started()) + translate_thread_->AbortSubprocesses(); + else + TranslateFinished(pp_error); } else { // Compare download completion pct (100% now), to compile completion pct. HistogramRatio(plugin_->uma_interface(), "NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", pexe_bytes_compiled_, pexe_size_); - } -} - -void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error, - FileStreamData data) { - PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%" - NACL_PRId32 ", data=%p)\n", pp_error, data ? &(*data)[0] : 0)); - DCHECK(translate_thread_.get()); - - // When we have received data, pp_error is set to the number of bytes - // received. - if (pp_error > 0) { - CHECK(data); - translate_thread_->PutBytes(data, pp_error); - pexe_size_ += pp_error; - } else { translate_thread_->EndStream(); } } -StreamCallback PnaclCoordinator::GetCallback() { - return callback_factory_.NewCallbackWithOutput( - &PnaclCoordinator::BitcodeStreamGotData); -} - void PnaclCoordinator::BitcodeGotCompiled(int32_t pp_error, int64_t bytes_compiled) { DCHECK(pp_error == PP_OK); pexe_bytes_compiled_ += bytes_compiled; - // If we don't know the expected total yet, ask. - if (expected_pexe_size_ == -1) { - int64_t amount_downloaded; // dummy variable. - streaming_downloader_->GetDownloadProgress(&amount_downloaded, - &expected_pexe_size_); - } // Hold off reporting the last few bytes of progress, since we don't know // when they are actually completely compiled. "bytes_compiled" only means // that bytes were sent to the compiler. diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h index 44a1d54..ac1a330 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h @@ -17,12 +17,12 @@ #include "ppapi/cpp/completion_callback.h" -#include "ppapi/native_client/src/trusted/plugin/callback_source.h" -#include "ppapi/native_client/src/trusted/plugin/file_downloader.h" #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h" +#include "ppapi/utility/completion_callback_factory.h" + struct PP_PNaClOptions; namespace plugin { @@ -51,7 +51,7 @@ class TempFile; // 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 CallbackSource<FileStreamData> { +class PnaclCoordinator { public: // Maximum number of object files passable to the translator. Cannot be // changed without changing the RPC signatures. @@ -69,12 +69,6 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { // BitcodeToNative has completed (and the finish_callback called). PP_FileHandle TakeTranslatedFileHandle(); - // Implement FileDownloader's template of the CallbackSource interface. - // This method returns a callback which will be called by the FileDownloader - // to stream the bitcode data as it arrives. The callback - // (BitcodeStreamGotData) passes it to llc over SRPC. - StreamCallback GetCallback(); - // Return a callback that should be notified when |bytes_compiled| bytes // have been compiled. pp::CompletionCallback GetCompileProgressCallback(int64_t bytes_compiled); @@ -92,6 +86,16 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { expected_pexe_size_) < kProgressEventSlopPct; } + + void BitcodeStreamCacheHit(PP_FileHandle handle); + void BitcodeStreamCacheMiss(int64_t expected_pexe_size); + + // 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: NACL_DISALLOW_COPY_AND_ASSIGN(PnaclCoordinator); @@ -104,19 +108,9 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { // Invoke to issue a GET request for bitcode. void OpenBitcodeStream(); - // Invoked when we've started an URL fetch for the pexe to check for - // caching metadata. - void BitcodeStreamDidOpen(int32_t pp_error); - // Invoked when we've gotten a temp FD for the nexe, either with the nexe - // data, or a writeable fd to save to. - void NexeFdDidOpen(int32_t pp_error); - // Invoked when a pexe data chunk arrives (when using streaming translation) - void BitcodeStreamGotData(int32_t pp_error, FileStreamData data); // Invoked when a pexe data chunk is compiled. void BitcodeGotCompiled(int32_t pp_error, int64_t bytes_compiled); - // Invoked when the pexe download finishes (using streaming translation) - void BitcodeStreamDidFinish(int32_t pp_error); // 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. @@ -180,12 +174,6 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { // Translated nexe file, produced by the linker. nacl::scoped_ptr<TempFile> temp_nexe_file_; - // Passed to the browser, which sets it to true if there is a translation - // cache hit. - PP_Bool is_cache_hit_; - - // Downloader for streaming translation - nacl::scoped_ptr<FileDownloader> streaming_downloader_; // Used to report information when errors (PPAPI or otherwise) are reported. ErrorInfo error_info_; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc index fff5382..8fb07ad 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc @@ -111,27 +111,16 @@ void PnaclTranslateThread::RunTranslate( } // Called from main thread to send bytes to the translator. -void PnaclTranslateThread::PutBytes(std::vector<char>* bytes, int count) { - PLUGIN_PRINTF(("PutBytes (this=%p, bytes=%p, size=%" NACL_PRIuS - ", count=%d)\n", - this, bytes, bytes ? bytes->size() : 0, count)); - size_t buffer_size = 0; +void PnaclTranslateThread::PutBytes(const void* bytes, int32_t count) { CHECK(bytes != NULL); - // Ensure that the buffer we send to the translation thread is the right size - // (count can be < the buffer size). This can be done without the lock. - buffer_size = bytes->size(); - bytes->resize(count); - NaClXMutexLock(&cond_mu_); - - data_buffers_.push_back(std::vector<char>()); - bytes->swap(data_buffers_.back()); // Avoid copying the buffer data. - + std::vector<char> v; + data_buffers_.push_back(v); + data_buffers_.back().insert(v.end(), + static_cast<const char*>(bytes), + static_cast<const char*>(bytes) + count); NaClXCondVarSignal(&buffer_cond_); NaClXMutexUnlock(&cond_mu_); - - // Ensure the buffer we send back to the coordinator is the expected size - bytes->resize(buffer_size); } void PnaclTranslateThread::EndStream() { diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h index ed0c7d7..60c1cba 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h @@ -61,7 +61,7 @@ class PnaclTranslateThread { void AbortSubprocesses(); // Send bitcode bytes to the translator. Called from the main thread. - void PutBytes(std::vector<char>* data, int count); + void PutBytes(const void* data, int count); // Notify the translator that the end of the bitcode stream has been reached. // Called from the main thread. @@ -69,6 +69,9 @@ class PnaclTranslateThread { int64_t GetCompileTime() const { return compile_time_; } + // Returns true if RunTranslate() has been called, false otherwise. + bool started() const { return plugin_ != NULL; } + private: // Helper thread entry point for translation. Takes a pointer to // PnaclTranslateThread and calls DoTranslate(). diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index f1fc368..c5e36d4 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -3322,11 +3322,6 @@ static PP_Bool Pnacl_M25_PPB_NaCl_Private_IsNonSFIModeEnabled(void) { return iface->IsNonSFIModeEnabled(); } -static int32_t Pnacl_M25_PPB_NaCl_Private_GetNexeFd(PP_Instance instance, const char* pexe_url, uint32_t abi_version, uint32_t opt_level, const char* headers, const char* extra_flags, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback* callback) { - const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; - return iface->GetNexeFd(instance, pexe_url, abi_version, opt_level, headers, extra_flags, is_hit, nexe_handle, *callback); -} - static void Pnacl_M25_PPB_NaCl_Private_ReportTranslationFinished(PP_Instance instance, PP_Bool success, int32_t opt_level, int64_t pexe_size, int64_t compile_time_us) { const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; iface->ReportTranslationFinished(instance, success, opt_level, pexe_size, compile_time_us); @@ -3477,6 +3472,11 @@ static void Pnacl_M25_PPB_NaCl_Private_SetPNaClStartTime(PP_Instance instance) { iface->SetPNaClStartTime(instance); } +static void Pnacl_M25_PPB_NaCl_Private_StreamPexe(PP_Instance instance, const char* pexe_url, int32_t opt_level, const struct PPP_PexeStreamHandler_1_0* stream_handler, void* stream_handler_user_data) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + iface->StreamPexe(instance, pexe_url, opt_level, stream_handler, stream_handler_user_data); +} + /* End wrapper methods for PPB_NaCl_Private_1_0 */ /* Begin wrapper methods for PPB_NetAddress_Private_0_1 */ @@ -4331,6 +4331,8 @@ static struct PP_Var Pnacl_M18_PPP_Instance_Private_GetInstanceObject(PP_Instanc /* End wrapper methods for PPP_Instance_Private_0_1 */ +/* Not generating wrapper methods for PPP_PexeStreamHandler_1_0 */ + /* Not generating wrapper interface for PPB_Audio_1_0 */ /* Not generating wrapper interface for PPB_Audio_1_1 */ @@ -5228,7 +5230,6 @@ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = { .CreateTemporaryFile = (PP_FileHandle (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_CreateTemporaryFile, .GetNumberOfProcessors = (int32_t (*)(void))&Pnacl_M25_PPB_NaCl_Private_GetNumberOfProcessors, .IsNonSFIModeEnabled = (PP_Bool (*)(void))&Pnacl_M25_PPB_NaCl_Private_IsNonSFIModeEnabled, - .GetNexeFd = (int32_t (*)(PP_Instance instance, const char* pexe_url, uint32_t abi_version, uint32_t opt_level, const char* headers, const char* extra_flags, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_GetNexeFd, .ReportTranslationFinished = (void (*)(PP_Instance instance, PP_Bool success, int32_t opt_level, int64_t pexe_size, int64_t compile_time_us))&Pnacl_M25_PPB_NaCl_Private_ReportTranslationFinished, .DispatchEvent = (void (*)(PP_Instance instance, PP_NaClEventType event_type, const char* resource_url, PP_Bool length_is_computable, uint64_t loaded_bytes, uint64_t total_bytes))&Pnacl_M25_PPB_NaCl_Private_DispatchEvent, .ReportLoadSuccess = (void (*)(PP_Instance instance, uint64_t loaded_bytes, uint64_t total_bytes))&Pnacl_M25_PPB_NaCl_Private_ReportLoadSuccess, @@ -5258,7 +5259,8 @@ static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = { .ReportSelLdrStatus = (void (*)(PP_Instance instance, int32_t load_status, int32_t max_status))&Pnacl_M25_PPB_NaCl_Private_ReportSelLdrStatus, .LogTranslateTime = (void (*)(const char* histogram_name, int64_t time_us))&Pnacl_M25_PPB_NaCl_Private_LogTranslateTime, .OpenManifestEntry = (void (*)(PP_Instance instance, PP_Bool is_helper_process, const char* key, struct PP_NaClFileInfo* file_info, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_OpenManifestEntry, - .SetPNaClStartTime = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_SetPNaClStartTime + .SetPNaClStartTime = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_SetPNaClStartTime, + .StreamPexe = (void (*)(PP_Instance instance, const char* pexe_url, int32_t opt_level, const struct PPP_PexeStreamHandler_1_0* stream_handler, void* stream_handler_user_data))&Pnacl_M25_PPB_NaCl_Private_StreamPexe }; static const struct PPB_NetAddress_Private_0_1 Pnacl_Wrappers_PPB_NetAddress_Private_0_1 = { @@ -5481,6 +5483,8 @@ static const struct PPP_Instance_Private_0_1 Pnacl_Wrappers_PPP_Instance_Private .GetInstanceObject = &Pnacl_M18_PPP_Instance_Private_GetInstanceObject }; +/* Not generating wrapper interface for PPP_PexeStreamHandler_1_0 */ + static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Compositor_0_1 = { .iface_macro = PPB_COMPOSITOR_INTERFACE_0_1, .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_Compositor_0_1, |