| Index: ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
|
| diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
|
| index 3669159f5e387c276daefd2907859bfcdba668fd..7b425a0c9501d62fe860ba499efec45cfdbff2aa 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);
|
| +}
|
|
|
| -// Out-of-line destructor to keep it from getting put in every .o where
|
| -// callback_source.h is included
|
| -template<>
|
| -CallbackSource<FileStreamData>::~CallbackSource() {}
|
| +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
|
| +};
|
| +
|
| +} // 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,74 @@ 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_.reset(new TempFile(plugin_, 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;
|
| +
|
| + for (int i = 0; i < split_module_count_; i++) {
|
| + PP_FileHandle obj_handle =
|
| + plugin_->nacl_interface()->CreateTemporaryFile(plugin_->pp_instance());
|
| + nacl::scoped_ptr<TempFile> temp_file(new TempFile(plugin_, obj_handle));
|
| + 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());
|
| +
|
| + PP_FileHandle nexe_handle =
|
| + plugin_->nacl_interface()->CreateTemporaryFile(plugin_->pp_instance());
|
| + temp_nexe_file_.reset(new TempFile(plugin_, nexe_handle));
|
| + // 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 +399,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.
|
|
|