Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: trunk/src/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc

Issue 406323003: Revert 284684 "Pepper: Delete FileDownloader in trusted plugin." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h" 5 #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h"
6 6
7 #include <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "native_client/src/include/checked_cast.h" 10 #include "native_client/src/include/checked_cast.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 uma.HistogramEnumeration("NaCl.Perf.PNaClCache.IsHit", 56 uma.HistogramEnumeration("NaCl.Perf.PNaClCache.IsHit",
57 hit, 2); 57 hit, 2);
58 } 58 }
59 59
60 nacl::string GetArchitectureAttributes(Plugin* plugin) { 60 nacl::string GetArchitectureAttributes(Plugin* plugin) {
61 pp::Var attrs_var(pp::PASS_REF, 61 pp::Var attrs_var(pp::PASS_REF,
62 plugin->nacl_interface()->GetCpuFeatureAttrs()); 62 plugin->nacl_interface()->GetCpuFeatureAttrs());
63 return attrs_var.AsString(); 63 return attrs_var.AsString();
64 } 64 }
65 65
66 void DidCacheHit(void* user_data, PP_FileHandle nexe_file_handle) { 66 } // namespace
67 PnaclCoordinator* coordinator = static_cast<PnaclCoordinator*>(user_data);
68 coordinator->BitcodeStreamCacheHit(nexe_file_handle);
69 }
70 67
71 void DidCacheMiss(void* user_data, int64_t expected_pexe_size) { 68 // Out-of-line destructor to keep it from getting put in every .o where
72 PnaclCoordinator* coordinator = static_cast<PnaclCoordinator*>(user_data); 69 // callback_source.h is included
73 coordinator->BitcodeStreamCacheMiss(expected_pexe_size); 70 template<>
74 } 71 CallbackSource<FileStreamData>::~CallbackSource() {}
75
76 void DidStreamData(void* user_data, const void* stream_data, int32_t length) {
77 PnaclCoordinator* coordinator = static_cast<PnaclCoordinator*>(user_data);
78 coordinator->BitcodeStreamGotData(stream_data, length);
79 }
80
81 void DidFinishStream(void* user_data, int32_t pp_error) {
82 PnaclCoordinator* coordinator = static_cast<PnaclCoordinator*>(user_data);
83 coordinator->BitcodeStreamDidFinish(pp_error);
84 }
85
86 PPP_PexeStreamHandler kPexeStreamHandler = {
87 &DidCacheHit,
88 &DidCacheMiss,
89 &DidStreamData,
90 &DidFinishStream
91 };
92
93 } // namespace
94 72
95 PnaclCoordinator* PnaclCoordinator::BitcodeToNative( 73 PnaclCoordinator* PnaclCoordinator::BitcodeToNative(
96 Plugin* plugin, 74 Plugin* plugin,
97 const nacl::string& pexe_url, 75 const nacl::string& pexe_url,
98 const PP_PNaClOptions& pnacl_options, 76 const PP_PNaClOptions& pnacl_options,
99 const pp::CompletionCallback& translate_notify_callback) { 77 const pp::CompletionCallback& translate_notify_callback) {
100 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", 78 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n",
101 static_cast<void*>(plugin), pexe_url.c_str())); 79 static_cast<void*>(plugin), pexe_url.c_str()));
102 PnaclCoordinator* coordinator = 80 PnaclCoordinator* coordinator =
103 new PnaclCoordinator(plugin, pexe_url, 81 new PnaclCoordinator(plugin, pexe_url,
(...skipping 18 matching lines...) Expand all
122 const PP_PNaClOptions& pnacl_options, 100 const PP_PNaClOptions& pnacl_options,
123 const pp::CompletionCallback& translate_notify_callback) 101 const pp::CompletionCallback& translate_notify_callback)
124 : translate_finish_error_(PP_OK), 102 : translate_finish_error_(PP_OK),
125 plugin_(plugin), 103 plugin_(plugin),
126 translate_notify_callback_(translate_notify_callback), 104 translate_notify_callback_(translate_notify_callback),
127 translation_finished_reported_(false), 105 translation_finished_reported_(false),
128 pexe_url_(pexe_url), 106 pexe_url_(pexe_url),
129 pnacl_options_(pnacl_options), 107 pnacl_options_(pnacl_options),
130 architecture_attributes_(GetArchitectureAttributes(plugin)), 108 architecture_attributes_(GetArchitectureAttributes(plugin)),
131 split_module_count_(1), 109 split_module_count_(1),
110 is_cache_hit_(PP_FALSE),
132 error_already_reported_(false), 111 error_already_reported_(false),
133 pexe_size_(0), 112 pexe_size_(0),
134 pexe_bytes_compiled_(0), 113 pexe_bytes_compiled_(0),
135 expected_pexe_size_(-1) { 114 expected_pexe_size_(-1) {
136 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", 115 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n",
137 static_cast<void*>(this), static_cast<void*>(plugin))); 116 static_cast<void*>(this), static_cast<void*>(plugin)));
138 callback_factory_.Initialize(this); 117 callback_factory_.Initialize(this);
139 } 118 }
140 119
141 PnaclCoordinator::~PnaclCoordinator() { 120 PnaclCoordinator::~PnaclCoordinator() {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 ReportPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_OTHER, 258 ReportPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_OTHER,
280 pp_error, 259 pp_error,
281 "Failed to open translated nexe."); 260 "Failed to open translated nexe.");
282 return; 261 return;
283 } 262 }
284 263
285 translate_notify_callback_.Run(pp_error); 264 translate_notify_callback_.Run(pp_error);
286 } 265 }
287 266
288 void PnaclCoordinator::OpenBitcodeStream() { 267 void PnaclCoordinator::OpenBitcodeStream() {
268 // Now open the pexe stream.
269 streaming_downloader_.reset(new FileDownloader(plugin_));
270 // Mark the request as requesting a PNaCl bitcode file,
271 // so that component updater can detect this user action.
272 streaming_downloader_->set_request_headers(
273 "Accept: application/x-pnacl, */*");
274
275 // Even though we haven't started downloading, create the translation
276 // thread object immediately. This ensures that any pieces of the file
277 // that get downloaded before the compilation thread is accepting
278 // SRPCs won't get dropped.
279 translate_thread_.reset(new PnaclTranslateThread());
280 if (translate_thread_ == NULL) {
281 ReportNonPpapiError(
282 PP_NACL_ERROR_PNACL_THREAD_CREATE,
283 "PnaclCoordinator: could not allocate translation thread.");
284 return;
285 }
286
287 pp::CompletionCallback cb =
288 callback_factory_.NewCallback(&PnaclCoordinator::BitcodeStreamDidOpen);
289 if (!streaming_downloader_->OpenStream(pexe_url_, cb, this)) {
290 ReportNonPpapiError(
291 PP_NACL_ERROR_PNACL_PEXE_FETCH_OTHER,
292 nacl::string("PnaclCoordinator: failed to open stream ") + pexe_url_);
293 return;
294 }
295 }
296
297 void PnaclCoordinator::BitcodeStreamDidOpen(int32_t pp_error) {
298 if (pp_error != PP_OK) {
299 BitcodeStreamDidFinish(pp_error);
300 // We have not spun up the translation process yet, so we need to call
301 // TranslateFinished here.
302 TranslateFinished(pp_error);
303 return;
304 }
305
289 // The component updater's resource throttles + OnDemand update/install 306 // The component updater's resource throttles + OnDemand update/install
290 // should block the URL request until the compiler is present. Now we 307 // should block the URL request until the compiler is present. Now we
291 // can load the resources (e.g. llc and ld nexes). 308 // can load the resources (e.g. llc and ld nexes).
292 resources_.reset(new PnaclResources(plugin_)); 309 resources_.reset(new PnaclResources(plugin_));
293 CHECK(resources_ != NULL); 310 CHECK(resources_ != NULL);
294 311
295 // The first step of loading resources: read the resource info file. 312 // The first step of loading resources: read the resource info file.
296 if (!resources_->ReadResourceInfo()) { 313 if (!resources_->ReadResourceInfo()) {
297 ExitWithError(); 314 ExitWithError();
298 return; 315 return;
299 } 316 }
300 317
301 // Second step of loading resources: call StartLoad to load pnacl-llc 318 // Second step of loading resources: call StartLoad to load pnacl-llc
302 // and pnacl-ld, based on the filenames found in the resource info file. 319 // and pnacl-ld, based on the filenames found in the resource info file.
303 if (!resources_->StartLoad()) { 320 if (!resources_->StartLoad()) {
304 ReportNonPpapiError( 321 ReportNonPpapiError(
305 PP_NACL_ERROR_PNACL_RESOURCE_FETCH, 322 PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
306 nacl::string("The Portable Native Client (pnacl) component is not " 323 nacl::string("The Portable Native Client (pnacl) component is not "
307 "installed. Please consult chrome://components for more " 324 "installed. Please consult chrome://components for more "
308 "information.")); 325 "information."));
309 return; 326 return;
310 } 327 }
311 328
312 // Even though we haven't started downloading, create the translation 329 // Okay, now that we've started the HTTP request for the pexe
313 // thread object immediately. This ensures that any pieces of the file 330 // and we've ensured that the PNaCl compiler + metadata is installed,
314 // that get downloaded before the compilation thread is accepting 331 // get the cache key from the response headers and from the
315 // SRPCs won't get dropped. 332 // compiler's version metadata.
316 translate_thread_.reset(new PnaclTranslateThread()); 333 nacl::string headers = streaming_downloader_->GetResponseHeaders();
317 if (translate_thread_ == NULL) { 334
318 ReportNonPpapiError( 335 temp_nexe_file_.reset(new TempFile(plugin_));
319 PP_NACL_ERROR_PNACL_THREAD_CREATE, 336 pp::CompletionCallback cb =
320 "PnaclCoordinator: could not allocate translation thread."); 337 callback_factory_.NewCallback(&PnaclCoordinator::NexeFdDidOpen);
338 int32_t nexe_fd_err =
339 plugin_->nacl_interface()->GetNexeFd(
340 plugin_->pp_instance(),
341 streaming_downloader_->full_url().c_str(),
342 // TODO(dschuff): Get this value from the pnacl json file after it
343 // rolls in from NaCl.
344 1,
345 pnacl_options_.opt_level,
346 headers.c_str(),
347 architecture_attributes_.c_str(), // Extra compile flags.
348 &is_cache_hit_,
349 temp_nexe_file_->internal_handle(),
350 cb.pp_completion_callback());
351 if (nexe_fd_err < PP_OK_COMPLETIONPENDING) {
352 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, nexe_fd_err,
353 nacl::string("Call to GetNexeFd failed"));
354 }
355 }
356
357 void PnaclCoordinator::NexeFdDidOpen(int32_t pp_error) {
358 PLUGIN_PRINTF(("PnaclCoordinator::NexeFdDidOpen (pp_error=%"
359 NACL_PRId32 ", hit=%d)\n", pp_error,
360 is_cache_hit_ == PP_TRUE));
361 if (pp_error < PP_OK) {
362 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, pp_error,
363 nacl::string("GetNexeFd failed"));
321 return; 364 return;
322 } 365 }
323 366
324 GetNaClInterface()->StreamPexe(plugin_->pp_instance(), 367 if (*temp_nexe_file_->internal_handle() == PP_kInvalidFileHandle) {
325 pexe_url_.c_str(),
326 pnacl_options_.opt_level,
327 &kPexeStreamHandler,
328 this);
329 }
330
331 void PnaclCoordinator::BitcodeStreamCacheHit(PP_FileHandle handle) {
332 HistogramEnumerateTranslationCache(plugin_->uma_interface(), true);
333 if (handle == PP_kInvalidFileHandle) {
334 ReportNonPpapiError( 368 ReportNonPpapiError(
335 PP_NACL_ERROR_PNACL_CREATE_TEMP, 369 PP_NACL_ERROR_PNACL_CREATE_TEMP,
336 nacl::string( 370 nacl::string(
337 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); 371 "PnaclCoordinator: Got bad temp file handle from GetNexeFd"));
338 BitcodeStreamDidFinish(PP_ERROR_FAILED);
339 return; 372 return;
340 } 373 }
341 *temp_nexe_file_->internal_handle() = handle; 374 HistogramEnumerateTranslationCache(plugin_->uma_interface(), is_cache_hit_);
342 // Open it for reading as the cached nexe file.
343 NexeReadDidOpen(temp_nexe_file_->Open(false));
344 }
345 375
346 void PnaclCoordinator::BitcodeStreamCacheMiss(int64_t expected_pexe_size) { 376 if (is_cache_hit_ == PP_TRUE) {
347 HistogramEnumerateTranslationCache(plugin_->uma_interface(), false); 377 // Cache hit -- no need to stream the rest of the file.
348 expected_pexe_size_ = expected_pexe_size; 378 streaming_downloader_.reset(NULL);
379 // Open it for reading as the cached nexe file.
380 NexeReadDidOpen(temp_nexe_file_->Open(false));
381 } else {
382 // Open an object file first so the translator can start writing to it
383 // during streaming translation.
384 for (int i = 0; i < split_module_count_; i++) {
385 nacl::scoped_ptr<TempFile> temp_file(new TempFile(plugin_));
386 int32_t pp_error = temp_file->Open(true);
387 if (pp_error != PP_OK) {
388 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP,
389 pp_error,
390 "Failed to open scratch object file.");
391 return;
392 } else {
393 obj_files_.push_back(temp_file.release());
394 }
395 }
396 invalid_desc_wrapper_.reset(plugin_->wrapper_factory()->MakeInvalid());
349 397
350 // Open an object file first so the translator can start writing to it 398 // Meanwhile, a miss means we know we need to stream the bitcode, so stream
351 // during streaming translation. 399 // the rest of it now. (Calling BeginStreaming means that the downloader
352 temp_nexe_file_.reset(new TempFile(plugin_)); 400 // will begin handing data to the coordinator, which is safe any time after
401 // the translate_thread_ object has been initialized).
402 pp::CompletionCallback finish_cb = callback_factory_.NewCallback(
403 &PnaclCoordinator::BitcodeStreamDidFinish);
404 streaming_downloader_->BeginStreaming(finish_cb);
353 405
354 for (int i = 0; i < split_module_count_; i++) { 406 // Open the nexe file for connecting ld and sel_ldr.
355 nacl::scoped_ptr<TempFile> temp_file(new TempFile(plugin_)); 407 // Start translation when done with this last step of setup!
356 int32_t pp_error = temp_file->Open(true); 408 RunTranslate(temp_nexe_file_->Open(true));
357 if (pp_error != PP_OK) {
358 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP,
359 pp_error,
360 "Failed to open scratch object file.");
361 return;
362 } else {
363 obj_files_.push_back(temp_file.release());
364 }
365 } 409 }
366 invalid_desc_wrapper_.reset(plugin_->wrapper_factory()->MakeInvalid());
367
368 // Open the nexe file for connecting ld and sel_ldr.
369 // Start translation when done with this last step of setup!
370 RunTranslate(temp_nexe_file_->Open(true));
371 }
372
373 void PnaclCoordinator::BitcodeStreamGotData(const void* data, int32_t length) {
374 DCHECK(translate_thread_.get());
375
376 translate_thread_->PutBytes(data, length);
377 if (data && length > 0)
378 pexe_size_ += length;
379 } 410 }
380 411
381 void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { 412 void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) {
382 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%" 413 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%"
383 NACL_PRId32 ")\n", pp_error)); 414 NACL_PRId32 ")\n", pp_error));
384 if (pp_error != PP_OK) { 415 if (pp_error != PP_OK) {
385 // Defer reporting the error and cleanup until after the translation 416 // Defer reporting the error and cleanup until after the translation
386 // thread returns, because it may be accessing the coordinator's 417 // thread returns, because it may be accessing the coordinator's
387 // objects or writing to the files. 418 // objects or writing to the files.
388 translate_finish_error_ = pp_error; 419 translate_finish_error_ = pp_error;
389 if (pp_error == PP_ERROR_ABORTED) { 420 if (pp_error == PP_ERROR_ABORTED) {
390 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_ABORTED, 421 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_ABORTED,
391 "PnaclCoordinator: pexe load failed (aborted)."); 422 "PnaclCoordinator: pexe load failed (aborted).");
392 } 423 }
393 if (pp_error == PP_ERROR_NOACCESS) { 424 if (pp_error == PP_ERROR_NOACCESS) {
394 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_NOACCESS, 425 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_NOACCESS,
395 "PnaclCoordinator: pexe load failed (no access)."); 426 "PnaclCoordinator: pexe load failed (no access).");
396 } else { 427 } else {
397 nacl::stringstream ss; 428 nacl::stringstream ss;
398 ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ")."; 429 ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ").";
399 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); 430 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_OTHER, ss.str());
400 } 431 }
401 432 translate_thread_->AbortSubprocesses();
402 if (translate_thread_->started())
403 translate_thread_->AbortSubprocesses();
404 else
405 TranslateFinished(pp_error);
406 } else { 433 } else {
407 // Compare download completion pct (100% now), to compile completion pct. 434 // Compare download completion pct (100% now), to compile completion pct.
408 HistogramRatio(plugin_->uma_interface(), 435 HistogramRatio(plugin_->uma_interface(),
409 "NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", 436 "NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded",
410 pexe_bytes_compiled_, pexe_size_); 437 pexe_bytes_compiled_, pexe_size_);
438 }
439 }
440
441 void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error,
442 FileStreamData data) {
443 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%"
444 NACL_PRId32 ", data=%p)\n", pp_error, data ? &(*data)[0] : 0));
445 DCHECK(translate_thread_.get());
446
447 // When we have received data, pp_error is set to the number of bytes
448 // received.
449 if (pp_error > 0) {
450 CHECK(data);
451 translate_thread_->PutBytes(data, pp_error);
452 pexe_size_ += pp_error;
453 } else {
411 translate_thread_->EndStream(); 454 translate_thread_->EndStream();
412 } 455 }
413 } 456 }
414 457
458 StreamCallback PnaclCoordinator::GetCallback() {
459 return callback_factory_.NewCallbackWithOutput(
460 &PnaclCoordinator::BitcodeStreamGotData);
461 }
462
415 void PnaclCoordinator::BitcodeGotCompiled(int32_t pp_error, 463 void PnaclCoordinator::BitcodeGotCompiled(int32_t pp_error,
416 int64_t bytes_compiled) { 464 int64_t bytes_compiled) {
417 DCHECK(pp_error == PP_OK); 465 DCHECK(pp_error == PP_OK);
418 pexe_bytes_compiled_ += bytes_compiled; 466 pexe_bytes_compiled_ += bytes_compiled;
467 // If we don't know the expected total yet, ask.
468 if (expected_pexe_size_ == -1) {
469 int64_t amount_downloaded; // dummy variable.
470 streaming_downloader_->GetDownloadProgress(&amount_downloaded,
471 &expected_pexe_size_);
472 }
419 // Hold off reporting the last few bytes of progress, since we don't know 473 // Hold off reporting the last few bytes of progress, since we don't know
420 // when they are actually completely compiled. "bytes_compiled" only means 474 // when they are actually completely compiled. "bytes_compiled" only means
421 // that bytes were sent to the compiler. 475 // that bytes were sent to the compiler.
422 if (expected_pexe_size_ != -1) { 476 if (expected_pexe_size_ != -1) {
423 if (!ShouldDelayProgressEvent()) { 477 if (!ShouldDelayProgressEvent()) {
424 GetNaClInterface()->DispatchEvent(plugin_->pp_instance(), 478 GetNaClInterface()->DispatchEvent(plugin_->pp_instance(),
425 PP_NACL_EVENT_PROGRESS, 479 PP_NACL_EVENT_PROGRESS,
426 pexe_url_.c_str(), 480 pexe_url_.c_str(),
427 PP_TRUE, 481 PP_TRUE,
428 pexe_bytes_compiled_, 482 pexe_bytes_compiled_,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 invalid_desc_wrapper_.get(), 519 invalid_desc_wrapper_.get(),
466 &error_info_, 520 &error_info_,
467 resources_.get(), 521 resources_.get(),
468 &pnacl_options_, 522 &pnacl_options_,
469 architecture_attributes_, 523 architecture_attributes_,
470 this, 524 this,
471 plugin_); 525 plugin_);
472 } 526 }
473 527
474 } // namespace plugin 528 } // namespace plugin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698