OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/service_worker/embedded_worker_instance.h" | 5 #include "content/browser/service_worker/embedded_worker_instance.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 status_ == EmbeddedWorkerStatus::STOPPED) | 435 status_ == EmbeddedWorkerStatus::STOPPED) |
436 << static_cast<int>(status_); | 436 << static_cast<int>(status_); |
437 devtools_proxy_.reset(); | 437 devtools_proxy_.reset(); |
438 if (registry_->GetWorker(embedded_worker_id_)) | 438 if (registry_->GetWorker(embedded_worker_id_)) |
439 registry_->RemoveWorker(process_id(), embedded_worker_id_); | 439 registry_->RemoveWorker(process_id(), embedded_worker_id_); |
440 process_handle_.reset(); | 440 process_handle_.reset(); |
441 } | 441 } |
442 | 442 |
443 void EmbeddedWorkerInstance::Start( | 443 void EmbeddedWorkerInstance::Start( |
444 std::unique_ptr<EmbeddedWorkerStartParams> params, | 444 std::unique_ptr<EmbeddedWorkerStartParams> params, |
| 445 base::WeakPtr<ServiceWorkerProviderHost> provider_host, |
445 mojom::ServiceWorkerEventDispatcherRequest dispatcher_request, | 446 mojom::ServiceWorkerEventDispatcherRequest dispatcher_request, |
446 const StatusCallback& callback) { | 447 const StatusCallback& callback) { |
447 restart_count_++; | 448 restart_count_++; |
448 if (!context_) { | 449 if (!context_) { |
449 callback.Run(SERVICE_WORKER_ERROR_ABORT); | 450 callback.Run(SERVICE_WORKER_ERROR_ABORT); |
450 // |this| may be destroyed by the callback. | 451 // |this| may be destroyed by the callback. |
451 return; | 452 return; |
452 } | 453 } |
453 DCHECK(status_ == EmbeddedWorkerStatus::STOPPED); | 454 DCHECK(status_ == EmbeddedWorkerStatus::STOPPED); |
454 | 455 |
455 DCHECK(!params->pause_after_download || !params->is_installed); | 456 DCHECK(!params->pause_after_download || !params->is_installed); |
456 DCHECK_NE(kInvalidServiceWorkerVersionId, params->service_worker_version_id); | 457 DCHECK_NE(kInvalidServiceWorkerVersionId, params->service_worker_version_id); |
457 step_time_ = base::TimeTicks::Now(); | 458 step_time_ = base::TimeTicks::Now(); |
458 status_ = EmbeddedWorkerStatus::STARTING; | 459 status_ = EmbeddedWorkerStatus::STARTING; |
459 starting_phase_ = ALLOCATING_PROCESS; | 460 starting_phase_ = ALLOCATING_PROCESS; |
460 network_accessed_for_script_ = false; | 461 network_accessed_for_script_ = false; |
| 462 provider_host_ = provider_host; |
461 for (auto& observer : listener_list_) | 463 for (auto& observer : listener_list_) |
462 observer.OnStarting(); | 464 observer.OnStarting(); |
463 | 465 |
464 params->embedded_worker_id = embedded_worker_id_; | 466 params->embedded_worker_id = embedded_worker_id_; |
465 params->worker_devtools_agent_route_id = MSG_ROUTING_NONE; | 467 params->worker_devtools_agent_route_id = MSG_ROUTING_NONE; |
466 params->wait_for_debugger = false; | 468 params->wait_for_debugger = false; |
467 params->settings.v8_cache_options = GetV8CacheOptions(); | 469 params->settings.v8_cache_options = GetV8CacheOptions(); |
468 | 470 |
469 mojom::EmbeddedWorkerInstanceClientRequest request = | 471 mojom::EmbeddedWorkerInstanceClientRequest request = |
470 mojo::MakeRequest(&client_); | 472 mojo::MakeRequest(&client_); |
471 client_.set_connection_error_handler( | 473 client_.set_connection_error_handler( |
472 base::Bind(&CallDetach, base::Unretained(this))); | 474 base::Bind(&CallDetach, base::Unretained(this))); |
473 | |
474 pending_dispatcher_request_ = std::move(dispatcher_request); | 475 pending_dispatcher_request_ = std::move(dispatcher_request); |
475 | 476 |
476 inflight_start_task_.reset( | 477 inflight_start_task_.reset( |
477 new StartTask(this, params->script_url, std::move(request))); | 478 new StartTask(this, params->script_url, std::move(request))); |
478 inflight_start_task_->Start(std::move(params), callback); | 479 inflight_start_task_->Start(std::move(params), callback); |
479 } | 480 } |
480 | 481 |
481 bool EmbeddedWorkerInstance::Stop() { | 482 bool EmbeddedWorkerInstance::Stop() { |
482 DCHECK(status_ == EmbeddedWorkerStatus::STARTING || | 483 DCHECK(status_ == EmbeddedWorkerStatus::STARTING || |
483 status_ == EmbeddedWorkerStatus::RUNNING) | 484 status_ == EmbeddedWorkerStatus::RUNNING) |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 step_time_ = base::TimeTicks(); | 583 step_time_ = base::TimeTicks(); |
583 } | 584 } |
584 for (auto& observer : listener_list_) | 585 for (auto& observer : listener_list_) |
585 observer.OnRegisteredToDevToolsManager(); | 586 observer.OnRegisteredToDevToolsManager(); |
586 } | 587 } |
587 | 588 |
588 ServiceWorkerStatusCode EmbeddedWorkerInstance::SendStartWorker( | 589 ServiceWorkerStatusCode EmbeddedWorkerInstance::SendStartWorker( |
589 std::unique_ptr<EmbeddedWorkerStartParams> params) { | 590 std::unique_ptr<EmbeddedWorkerStartParams> params) { |
590 if (!context_) | 591 if (!context_) |
591 return SERVICE_WORKER_ERROR_ABORT; | 592 return SERVICE_WORKER_ERROR_ABORT; |
| 593 DCHECK(pending_dispatcher_request_.is_pending()); |
592 | 594 |
593 DCHECK(!instance_host_binding_.is_bound()); | 595 DCHECK(!instance_host_binding_.is_bound()); |
594 mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo host_ptr_info; | 596 mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo host_ptr_info; |
595 instance_host_binding_.Bind(mojo::MakeRequest(&host_ptr_info)); | 597 instance_host_binding_.Bind(mojo::MakeRequest(&host_ptr_info)); |
596 | 598 |
597 DCHECK(pending_dispatcher_request_.is_pending()); | 599 mojom::ServiceWorkerProviderClientInfoPtr provider_client_info = |
| 600 mojom::ServiceWorkerProviderClientInfo::New(); |
| 601 provider_host_->CompleteStartWorkerPreparation(process_id(), |
| 602 &provider_client_info); |
| 603 |
598 client_->StartWorker(*params, std::move(pending_dispatcher_request_), | 604 client_->StartWorker(*params, std::move(pending_dispatcher_request_), |
599 std::move(host_ptr_info)); | 605 std::move(host_ptr_info), |
| 606 std::move(provider_client_info)); |
600 registry_->BindWorkerToProcess(process_id(), embedded_worker_id()); | 607 registry_->BindWorkerToProcess(process_id(), embedded_worker_id()); |
| 608 |
601 OnStartWorkerMessageSent(); | 609 OnStartWorkerMessageSent(); |
602 // Once the start worker message is received, renderer side will prepare a | 610 // Once the start worker message is received, renderer side will prepare a |
603 // shadow page for getting worker script. | 611 // shadow page for getting worker script. |
604 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "PREPARING_SCRIPT_LOAD", | 612 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "PREPARING_SCRIPT_LOAD", |
605 this); | 613 this); |
606 return SERVICE_WORKER_OK; | 614 return SERVICE_WORKER_OK; |
607 } | 615 } |
608 | 616 |
609 void EmbeddedWorkerInstance::OnStartWorkerMessageSent() { | 617 void EmbeddedWorkerInstance::OnStartWorkerMessageSent() { |
610 if (!step_time_.is_null()) { | 618 if (!step_time_.is_null()) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 void EmbeddedWorkerInstance::OnWorkerVersionInstalled() { | 702 void EmbeddedWorkerInstance::OnWorkerVersionInstalled() { |
695 if (devtools_proxy_) | 703 if (devtools_proxy_) |
696 devtools_proxy_->NotifyWorkerVersionInstalled(); | 704 devtools_proxy_->NotifyWorkerVersionInstalled(); |
697 } | 705 } |
698 | 706 |
699 void EmbeddedWorkerInstance::OnWorkerVersionDoomed() { | 707 void EmbeddedWorkerInstance::OnWorkerVersionDoomed() { |
700 if (devtools_proxy_) | 708 if (devtools_proxy_) |
701 devtools_proxy_->NotifyWorkerVersionDoomed(); | 709 devtools_proxy_->NotifyWorkerVersionDoomed(); |
702 } | 710 } |
703 | 711 |
704 void EmbeddedWorkerInstance::OnThreadStarted(int thread_id, int provider_id) { | 712 void EmbeddedWorkerInstance::OnThreadStarted(int thread_id) { |
705 if (!context_ || !inflight_start_task_) | 713 if (!context_ || !inflight_start_task_) |
706 return; | 714 return; |
707 | 715 |
708 ServiceWorkerProviderHost* provider_host = | |
709 context_->GetProviderHost(process_id(), provider_id); | |
710 if (!provider_host) { | |
711 bad_message::ReceivedBadMessage( | |
712 process_id(), bad_message::SWDH_WORKER_SCRIPT_LOAD_NO_HOST); | |
713 return; | |
714 } | |
715 | |
716 provider_host->SetReadyToSendMessagesToWorker(thread_id); | |
717 | |
718 TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "LAUNCHING_WORKER_THREAD", | 716 TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "LAUNCHING_WORKER_THREAD", |
719 this); | 717 this); |
720 // Renderer side has started to evaluate the loaded worker script. | 718 // Renderer side has started to evaluate the loaded worker script. |
721 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "EVALUATING_SCRIPT", this); | 719 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "EVALUATING_SCRIPT", this); |
722 starting_phase_ = THREAD_STARTED; | 720 starting_phase_ = THREAD_STARTED; |
723 if (!step_time_.is_null()) { | 721 if (!step_time_.is_null()) { |
724 base::TimeDelta duration = UpdateStepTime(); | 722 base::TimeDelta duration = UpdateStepTime(); |
725 if (inflight_start_task_->is_installed()) | 723 if (inflight_start_task_->is_installed()) |
726 ServiceWorkerMetrics::RecordTimeToStartThread(duration, start_situation_); | 724 ServiceWorkerMetrics::RecordTimeToStartThread(duration, start_situation_); |
727 } | 725 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 } | 802 } |
805 | 803 |
806 void EmbeddedWorkerInstance::OnDetached() { | 804 void EmbeddedWorkerInstance::OnDetached() { |
807 EmbeddedWorkerStatus old_status = status_; | 805 EmbeddedWorkerStatus old_status = status_; |
808 ReleaseProcess(); | 806 ReleaseProcess(); |
809 for (auto& observer : listener_list_) | 807 for (auto& observer : listener_list_) |
810 observer.OnDetached(old_status); | 808 observer.OnDetached(old_status); |
811 } | 809 } |
812 | 810 |
813 void EmbeddedWorkerInstance::Detach() { | 811 void EmbeddedWorkerInstance::Detach() { |
| 812 if (status() == EmbeddedWorkerStatus::STOPPED) |
| 813 return; |
814 registry_->DetachWorker(process_id(), embedded_worker_id()); | 814 registry_->DetachWorker(process_id(), embedded_worker_id()); |
815 OnDetached(); | 815 OnDetached(); |
816 } | 816 } |
817 | 817 |
818 base::WeakPtr<EmbeddedWorkerInstance> EmbeddedWorkerInstance::AsWeakPtr() { | 818 base::WeakPtr<EmbeddedWorkerInstance> EmbeddedWorkerInstance::AsWeakPtr() { |
819 return weak_factory_.GetWeakPtr(); | 819 return weak_factory_.GetWeakPtr(); |
820 } | 820 } |
821 | 821 |
822 bool EmbeddedWorkerInstance::OnMessageReceived(const IPC::Message& message) { | 822 bool EmbeddedWorkerInstance::OnMessageReceived(const IPC::Message& message) { |
823 for (auto& listener : listener_list_) { | 823 for (auto& listener : listener_list_) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "SCRIPT_DOWNLOADING", | 885 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "SCRIPT_DOWNLOADING", |
886 this); | 886 this); |
887 starting_phase_ = SCRIPT_DOWNLOADING; | 887 starting_phase_ = SCRIPT_DOWNLOADING; |
888 network_accessed_for_script_ = true; | 888 network_accessed_for_script_ = true; |
889 } | 889 } |
890 | 890 |
891 void EmbeddedWorkerInstance::ReleaseProcess() { | 891 void EmbeddedWorkerInstance::ReleaseProcess() { |
892 // Abort an inflight start task. | 892 // Abort an inflight start task. |
893 inflight_start_task_.reset(); | 893 inflight_start_task_.reset(); |
894 | 894 |
895 client_.reset(); | |
896 instance_host_binding_.Close(); | 895 instance_host_binding_.Close(); |
897 devtools_proxy_.reset(); | 896 devtools_proxy_.reset(); |
898 process_handle_.reset(); | 897 process_handle_.reset(); |
899 status_ = EmbeddedWorkerStatus::STOPPED; | 898 status_ = EmbeddedWorkerStatus::STOPPED; |
900 starting_phase_ = NOT_STARTING; | 899 starting_phase_ = NOT_STARTING; |
901 thread_id_ = kInvalidEmbeddedWorkerThreadId; | 900 thread_id_ = kInvalidEmbeddedWorkerThreadId; |
902 } | 901 } |
903 | 902 |
904 void EmbeddedWorkerInstance::OnStartFailed(const StatusCallback& callback, | 903 void EmbeddedWorkerInstance::OnStartFailed(const StatusCallback& callback, |
905 ServiceWorkerStatusCode status) { | 904 ServiceWorkerStatusCode status) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 case SCRIPT_READ_FINISHED: | 971 case SCRIPT_READ_FINISHED: |
973 return "Script read finished"; | 972 return "Script read finished"; |
974 case STARTING_PHASE_MAX_VALUE: | 973 case STARTING_PHASE_MAX_VALUE: |
975 NOTREACHED(); | 974 NOTREACHED(); |
976 } | 975 } |
977 NOTREACHED() << phase; | 976 NOTREACHED() << phase; |
978 return std::string(); | 977 return std::string(); |
979 } | 978 } |
980 | 979 |
981 } // namespace content | 980 } // namespace content |
OLD | NEW |