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

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

Issue 393693004: Pepper: Delete FileDownloader in trusted plugin. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: STL fix 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) {
67 PnaclCoordinator* coordinator = static_cast<PnaclCoordinator*>(user_data);
68 coordinator->BitcodeStreamCacheHit(nexe_file_handle);
69 }
70
71 void DidCacheMiss(void* user_data, int64_t expected_pexe_size) {
72 PnaclCoordinator* coordinator = static_cast<PnaclCoordinator*>(user_data);
73 coordinator->BitcodeStreamCacheMiss(expected_pexe_size);
74 }
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
66 } // namespace 93 } // namespace
67 94
68 // Out-of-line destructor to keep it from getting put in every .o where
69 // callback_source.h is included
70 template<>
71 CallbackSource<FileStreamData>::~CallbackSource() {}
72
73 PnaclCoordinator* PnaclCoordinator::BitcodeToNative( 95 PnaclCoordinator* PnaclCoordinator::BitcodeToNative(
74 Plugin* plugin, 96 Plugin* plugin,
75 const nacl::string& pexe_url, 97 const nacl::string& pexe_url,
76 const PP_PNaClOptions& pnacl_options, 98 const PP_PNaClOptions& pnacl_options,
77 const pp::CompletionCallback& translate_notify_callback) { 99 const pp::CompletionCallback& translate_notify_callback) {
78 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", 100 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n",
79 static_cast<void*>(plugin), pexe_url.c_str())); 101 static_cast<void*>(plugin), pexe_url.c_str()));
80 PnaclCoordinator* coordinator = 102 PnaclCoordinator* coordinator =
81 new PnaclCoordinator(plugin, pexe_url, 103 new PnaclCoordinator(plugin, pexe_url,
82 pnacl_options, 104 pnacl_options,
(...skipping 17 matching lines...) Expand all
100 const PP_PNaClOptions& pnacl_options, 122 const PP_PNaClOptions& pnacl_options,
101 const pp::CompletionCallback& translate_notify_callback) 123 const pp::CompletionCallback& translate_notify_callback)
102 : translate_finish_error_(PP_OK), 124 : translate_finish_error_(PP_OK),
103 plugin_(plugin), 125 plugin_(plugin),
104 translate_notify_callback_(translate_notify_callback), 126 translate_notify_callback_(translate_notify_callback),
105 translation_finished_reported_(false), 127 translation_finished_reported_(false),
106 pexe_url_(pexe_url), 128 pexe_url_(pexe_url),
107 pnacl_options_(pnacl_options), 129 pnacl_options_(pnacl_options),
108 architecture_attributes_(GetArchitectureAttributes(plugin)), 130 architecture_attributes_(GetArchitectureAttributes(plugin)),
109 split_module_count_(1), 131 split_module_count_(1),
110 is_cache_hit_(PP_FALSE),
111 error_already_reported_(false), 132 error_already_reported_(false),
112 pexe_size_(0), 133 pexe_size_(0),
113 pexe_bytes_compiled_(0), 134 pexe_bytes_compiled_(0),
114 expected_pexe_size_(-1) { 135 expected_pexe_size_(-1) {
115 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", 136 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n",
116 static_cast<void*>(this), static_cast<void*>(plugin))); 137 static_cast<void*>(this), static_cast<void*>(plugin)));
117 callback_factory_.Initialize(this); 138 callback_factory_.Initialize(this);
118 } 139 }
119 140
120 PnaclCoordinator::~PnaclCoordinator() { 141 PnaclCoordinator::~PnaclCoordinator() {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 ReportPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_OTHER, 279 ReportPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_OTHER,
259 pp_error, 280 pp_error,
260 "Failed to open translated nexe."); 281 "Failed to open translated nexe.");
261 return; 282 return;
262 } 283 }
263 284
264 translate_notify_callback_.Run(pp_error); 285 translate_notify_callback_.Run(pp_error);
265 } 286 }
266 287
267 void PnaclCoordinator::OpenBitcodeStream() { 288 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
306 // The component updater's resource throttles + OnDemand update/install 289 // The component updater's resource throttles + OnDemand update/install
307 // should block the URL request until the compiler is present. Now we 290 // should block the URL request until the compiler is present. Now we
308 // can load the resources (e.g. llc and ld nexes). 291 // can load the resources (e.g. llc and ld nexes).
309 resources_.reset(new PnaclResources(plugin_)); 292 resources_.reset(new PnaclResources(plugin_));
310 CHECK(resources_ != NULL); 293 CHECK(resources_ != NULL);
311 294
312 // The first step of loading resources: read the resource info file. 295 // The first step of loading resources: read the resource info file.
313 if (!resources_->ReadResourceInfo()) { 296 if (!resources_->ReadResourceInfo()) {
314 ExitWithError(); 297 ExitWithError();
315 return; 298 return;
316 } 299 }
317 300
318 // Second step of loading resources: call StartLoad to load pnacl-llc 301 // Second step of loading resources: call StartLoad to load pnacl-llc
319 // and pnacl-ld, based on the filenames found in the resource info file. 302 // and pnacl-ld, based on the filenames found in the resource info file.
320 if (!resources_->StartLoad()) { 303 if (!resources_->StartLoad()) {
321 ReportNonPpapiError( 304 ReportNonPpapiError(
322 PP_NACL_ERROR_PNACL_RESOURCE_FETCH, 305 PP_NACL_ERROR_PNACL_RESOURCE_FETCH,
323 nacl::string("The Portable Native Client (pnacl) component is not " 306 nacl::string("The Portable Native Client (pnacl) component is not "
324 "installed. Please consult chrome://components for more " 307 "installed. Please consult chrome://components for more "
325 "information.")); 308 "information."));
326 return; 309 return;
327 } 310 }
328 311
329 // Okay, now that we've started the HTTP request for the pexe 312 // Even though we haven't started downloading, create the translation
330 // and we've ensured that the PNaCl compiler + metadata is installed, 313 // thread object immediately. This ensures that any pieces of the file
331 // get the cache key from the response headers and from the 314 // that get downloaded before the compilation thread is accepting
332 // compiler's version metadata. 315 // SRPCs won't get dropped.
333 nacl::string headers = streaming_downloader_->GetResponseHeaders(); 316 translate_thread_.reset(new PnaclTranslateThread());
334 317 if (translate_thread_ == NULL) {
335 temp_nexe_file_.reset(new TempFile(plugin_)); 318 ReportNonPpapiError(
336 pp::CompletionCallback cb = 319 PP_NACL_ERROR_PNACL_THREAD_CREATE,
337 callback_factory_.NewCallback(&PnaclCoordinator::NexeFdDidOpen); 320 "PnaclCoordinator: could not allocate translation thread.");
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"));
364 return; 321 return;
365 } 322 }
366 323
367 if (*temp_nexe_file_->internal_handle() == PP_kInvalidFileHandle) { 324 GetNaClInterface()->StreamPexe(plugin_->pp_instance(),
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) {
368 ReportNonPpapiError( 334 ReportNonPpapiError(
369 PP_NACL_ERROR_PNACL_CREATE_TEMP, 335 PP_NACL_ERROR_PNACL_CREATE_TEMP,
370 nacl::string( 336 nacl::string(
371 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); 337 "PnaclCoordinator: Got bad temp file handle from GetNexeFd"));
338 BitcodeStreamDidFinish(PP_ERROR_FAILED);
372 return; 339 return;
373 } 340 }
374 HistogramEnumerateTranslationCache(plugin_->uma_interface(), is_cache_hit_); 341 temp_nexe_file_.reset(new TempFile(plugin_, handle));
342 // Open it for reading as the cached nexe file.
343 NexeReadDidOpen(temp_nexe_file_->Open(false));
344 }
375 345
376 if (is_cache_hit_ == PP_TRUE) { 346 void PnaclCoordinator::BitcodeStreamCacheMiss(int64_t expected_pexe_size) {
377 // Cache hit -- no need to stream the rest of the file. 347 HistogramEnumerateTranslationCache(plugin_->uma_interface(), false);
378 streaming_downloader_.reset(NULL); 348 expected_pexe_size_ = expected_pexe_size;
379 // Open it for reading as the cached nexe file. 349
380 NexeReadDidOpen(temp_nexe_file_->Open(false)); 350 for (int i = 0; i < split_module_count_; i++) {
381 } else { 351 PP_FileHandle obj_handle =
382 // Open an object file first so the translator can start writing to it 352 plugin_->nacl_interface()->CreateTemporaryFile(plugin_->pp_instance());
383 // during streaming translation. 353 nacl::scoped_ptr<TempFile> temp_file(new TempFile(plugin_, obj_handle));
384 for (int i = 0; i < split_module_count_; i++) { 354 int32_t pp_error = temp_file->Open(true);
385 nacl::scoped_ptr<TempFile> temp_file(new TempFile(plugin_)); 355 if (pp_error != PP_OK) {
386 int32_t pp_error = temp_file->Open(true); 356 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP,
387 if (pp_error != PP_OK) { 357 pp_error,
388 ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, 358 "Failed to open scratch object file.");
389 pp_error, 359 return;
390 "Failed to open scratch object file."); 360 } else {
391 return; 361 obj_files_.push_back(temp_file.release());
392 } else {
393 obj_files_.push_back(temp_file.release());
394 }
395 } 362 }
396 invalid_desc_wrapper_.reset(plugin_->wrapper_factory()->MakeInvalid()); 363 }
364 invalid_desc_wrapper_.reset(plugin_->wrapper_factory()->MakeInvalid());
397 365
398 // Meanwhile, a miss means we know we need to stream the bitcode, so stream 366 PP_FileHandle nexe_handle =
399 // the rest of it now. (Calling BeginStreaming means that the downloader 367 plugin_->nacl_interface()->CreateTemporaryFile(plugin_->pp_instance());
400 // will begin handing data to the coordinator, which is safe any time after 368 temp_nexe_file_.reset(new TempFile(plugin_, nexe_handle));
401 // the translate_thread_ object has been initialized). 369 // Open the nexe file for connecting ld and sel_ldr.
402 pp::CompletionCallback finish_cb = callback_factory_.NewCallback( 370 // Start translation when done with this last step of setup!
403 &PnaclCoordinator::BitcodeStreamDidFinish); 371 RunTranslate(temp_nexe_file_->Open(true));
404 streaming_downloader_->BeginStreaming(finish_cb); 372 }
405 373
406 // Open the nexe file for connecting ld and sel_ldr. 374 void PnaclCoordinator::BitcodeStreamGotData(const void* data, int32_t length) {
407 // Start translation when done with this last step of setup! 375 DCHECK(translate_thread_.get());
408 RunTranslate(temp_nexe_file_->Open(true)); 376
409 } 377 translate_thread_->PutBytes(data, length);
378 if (data && length > 0)
379 pexe_size_ += length;
410 } 380 }
411 381
412 void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { 382 void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) {
413 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%" 383 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%"
414 NACL_PRId32 ")\n", pp_error)); 384 NACL_PRId32 ")\n", pp_error));
415 if (pp_error != PP_OK) { 385 if (pp_error != PP_OK) {
416 // Defer reporting the error and cleanup until after the translation 386 // Defer reporting the error and cleanup until after the translation
417 // thread returns, because it may be accessing the coordinator's 387 // thread returns, because it may be accessing the coordinator's
418 // objects or writing to the files. 388 // objects or writing to the files.
419 translate_finish_error_ = pp_error; 389 translate_finish_error_ = pp_error;
420 if (pp_error == PP_ERROR_ABORTED) { 390 if (pp_error == PP_ERROR_ABORTED) {
421 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_ABORTED, 391 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_ABORTED,
422 "PnaclCoordinator: pexe load failed (aborted)."); 392 "PnaclCoordinator: pexe load failed (aborted).");
423 } 393 }
424 if (pp_error == PP_ERROR_NOACCESS) { 394 if (pp_error == PP_ERROR_NOACCESS) {
425 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_NOACCESS, 395 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_NOACCESS,
426 "PnaclCoordinator: pexe load failed (no access)."); 396 "PnaclCoordinator: pexe load failed (no access).");
427 } else { 397 } else {
428 nacl::stringstream ss; 398 nacl::stringstream ss;
429 ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ")."; 399 ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ").";
430 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); 400 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_OTHER, ss.str());
431 } 401 }
432 translate_thread_->AbortSubprocesses(); 402
403 if (translate_thread_->started())
404 translate_thread_->AbortSubprocesses();
405 else
406 TranslateFinished(pp_error);
433 } else { 407 } else {
434 // Compare download completion pct (100% now), to compile completion pct. 408 // Compare download completion pct (100% now), to compile completion pct.
435 HistogramRatio(plugin_->uma_interface(), 409 HistogramRatio(plugin_->uma_interface(),
436 "NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", 410 "NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded",
437 pexe_bytes_compiled_, pexe_size_); 411 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 {
454 translate_thread_->EndStream(); 412 translate_thread_->EndStream();
455 } 413 }
456 } 414 }
457 415
458 StreamCallback PnaclCoordinator::GetCallback() {
459 return callback_factory_.NewCallbackWithOutput(
460 &PnaclCoordinator::BitcodeStreamGotData);
461 }
462
463 void PnaclCoordinator::BitcodeGotCompiled(int32_t pp_error, 416 void PnaclCoordinator::BitcodeGotCompiled(int32_t pp_error,
464 int64_t bytes_compiled) { 417 int64_t bytes_compiled) {
465 DCHECK(pp_error == PP_OK); 418 DCHECK(pp_error == PP_OK);
466 pexe_bytes_compiled_ += bytes_compiled; 419 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 }
473 // Hold off reporting the last few bytes of progress, since we don't know 420 // Hold off reporting the last few bytes of progress, since we don't know
474 // when they are actually completely compiled. "bytes_compiled" only means 421 // when they are actually completely compiled. "bytes_compiled" only means
475 // that bytes were sent to the compiler. 422 // that bytes were sent to the compiler.
476 if (expected_pexe_size_ != -1) { 423 if (expected_pexe_size_ != -1) {
477 if (!ShouldDelayProgressEvent()) { 424 if (!ShouldDelayProgressEvent()) {
478 GetNaClInterface()->DispatchEvent(plugin_->pp_instance(), 425 GetNaClInterface()->DispatchEvent(plugin_->pp_instance(),
479 PP_NACL_EVENT_PROGRESS, 426 PP_NACL_EVENT_PROGRESS,
480 pexe_url_.c_str(), 427 pexe_url_.c_str(),
481 PP_TRUE, 428 PP_TRUE,
482 pexe_bytes_compiled_, 429 pexe_bytes_compiled_,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 invalid_desc_wrapper_.get(), 466 invalid_desc_wrapper_.get(),
520 &error_info_, 467 &error_info_,
521 resources_.get(), 468 resources_.get(),
522 &pnacl_options_, 469 &pnacl_options_,
523 architecture_attributes_, 470 architecture_attributes_,
524 this, 471 this,
525 plugin_); 472 plugin_);
526 } 473 }
527 474
528 } // namespace plugin 475 } // namespace plugin
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698