| Index: content/browser/service_worker/embedded_worker_instance.cc
|
| diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
|
| index 24d2a9529a9843eb6dbf7c36e44efeabd748dd4d..6b38dc10d37b168b7468e6d6142f830f8b8cf1e6 100644
|
| --- a/content/browser/service_worker/embedded_worker_instance.cc
|
| +++ b/content/browser/service_worker/embedded_worker_instance.cc
|
| @@ -4,14 +4,20 @@
|
|
|
| #include "content/browser/service_worker/embedded_worker_instance.h"
|
|
|
| +#include "base/bind_helpers.h"
|
| +#include "content/browser/devtools/embedded_worker_devtools_manager.h"
|
| #include "content/browser/service_worker/embedded_worker_registry.h"
|
| +#include "content/browser/service_worker/service_worker_context_core.h"
|
| #include "content/common/service_worker/embedded_worker_messages.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/render_process_host.h"
|
| #include "ipc/ipc_message.h"
|
| #include "url/gurl.h"
|
|
|
| namespace content {
|
|
|
| namespace {
|
| +
|
| // Functor to sort by the .second element of a struct.
|
| struct SecondGreater {
|
| template <typename Value>
|
| @@ -19,9 +25,73 @@ struct SecondGreater {
|
| return lhs.second > rhs.second;
|
| }
|
| };
|
| +
|
| +void NotifyWorkerContextStarted(int worker_process_id, int worker_route_id) {
|
| + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(
|
| + NotifyWorkerContextStarted, worker_process_id, worker_route_id));
|
| + return;
|
| + }
|
| + EmbeddedWorkerDevToolsManager::GetInstance()->WorkerContextStarted(
|
| + worker_process_id, worker_route_id);
|
| +}
|
| +
|
| +void NotifyWorkerDestroyed(int worker_process_id, int worker_route_id) {
|
| + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(NotifyWorkerDestroyed, worker_process_id, worker_route_id));
|
| + return;
|
| + }
|
| + EmbeddedWorkerDevToolsManager::GetInstance()->WorkerDestroyed(
|
| + worker_process_id, worker_route_id);
|
| +}
|
| +
|
| +void RegisterToWorkerDevToolsManager(
|
| + int process_id,
|
| + const ServiceWorkerContextCore* const service_worker_context,
|
| + int64 service_worker_version_id,
|
| + const base::Callback<void(int worker_devtools_agent_route_id,
|
| + bool pause_on_start)>& callback) {
|
| + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + BrowserThread::PostTask(BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(RegisterToWorkerDevToolsManager,
|
| + process_id,
|
| + service_worker_context,
|
| + service_worker_version_id,
|
| + callback));
|
| + return;
|
| + }
|
| + int worker_devtools_agent_route_id = MSG_ROUTING_NONE;
|
| + bool pause_on_start = false;
|
| + if (RenderProcessHost* rph = RenderProcessHost::FromID(process_id)) {
|
| + // |rph| may be NULL in unit tests.
|
| + worker_devtools_agent_route_id = rph->GetNextRoutingID();
|
| + pause_on_start =
|
| + EmbeddedWorkerDevToolsManager::GetInstance()->ServiceWorkerCreated(
|
| + process_id,
|
| + worker_devtools_agent_route_id,
|
| + service_worker_context,
|
| + service_worker_version_id);
|
| + }
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO,
|
| + FROM_HERE,
|
| + base::Bind(callback, worker_devtools_agent_route_id, pause_on_start));
|
| +}
|
| +
|
| } // namespace
|
|
|
| EmbeddedWorkerInstance::~EmbeddedWorkerInstance() {
|
| + if (worker_devtools_agent_route_id_ != MSG_ROUTING_NONE)
|
| + NotifyWorkerDestroyed(process_id_, worker_devtools_agent_route_id_);
|
| + if (context_ && process_id_ != -1)
|
| + context_->process_manager()->ReleaseWorkerProcess(process_id_);
|
| registry_->RemoveWorker(process_id_, embedded_worker_id_);
|
| }
|
|
|
| @@ -30,15 +100,28 @@ void EmbeddedWorkerInstance::Start(int64 service_worker_version_id,
|
| const GURL& script_url,
|
| const std::vector<int>& possible_process_ids,
|
| const StatusCallback& callback) {
|
| + if (!context_) {
|
| + callback.Run(SERVICE_WORKER_ERROR_ABORT);
|
| + return;
|
| + }
|
| DCHECK(status_ == STOPPED);
|
| status_ = STARTING;
|
| - std::vector<int> ordered_process_ids = SortProcesses(possible_process_ids);
|
| - registry_->StartWorker(ordered_process_ids,
|
| - embedded_worker_id_,
|
| - service_worker_version_id,
|
| - scope,
|
| - script_url,
|
| - callback);
|
| + scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params(
|
| + new EmbeddedWorkerMsg_StartWorker_Params());
|
| + params->embedded_worker_id = embedded_worker_id_;
|
| + params->service_worker_version_id = service_worker_version_id;
|
| + params->scope = scope;
|
| + params->script_url = script_url;
|
| + params->worker_devtools_agent_route_id = MSG_ROUTING_NONE;
|
| + params->pause_on_start = false;
|
| + context_->process_manager()->AllocateWorkerProcess(
|
| + SortProcesses(possible_process_ids),
|
| + script_url,
|
| + base::Bind(&EmbeddedWorkerInstance::RunProcessAllocated,
|
| + weak_factory_.GetWeakPtr(),
|
| + context_,
|
| + base::Passed(¶ms),
|
| + callback));
|
| }
|
|
|
| ServiceWorkerStatusCode EmbeddedWorkerInstance::Stop() {
|
| @@ -75,32 +158,76 @@ void EmbeddedWorkerInstance::ReleaseProcessReference(int process_id) {
|
| process_refs_.erase(found);
|
| }
|
|
|
| -EmbeddedWorkerInstance::EmbeddedWorkerInstance(EmbeddedWorkerRegistry* registry,
|
| - int embedded_worker_id)
|
| - : registry_(registry),
|
| +EmbeddedWorkerInstance::EmbeddedWorkerInstance(
|
| + base::WeakPtr<ServiceWorkerContextCore> context,
|
| + int embedded_worker_id)
|
| + : context_(context),
|
| + registry_(context->embedded_worker_registry()),
|
| embedded_worker_id_(embedded_worker_id),
|
| status_(STOPPED),
|
| process_id_(-1),
|
| thread_id_(-1),
|
| - worker_devtools_agent_route_id_(MSG_ROUTING_NONE) {
|
| + worker_devtools_agent_route_id_(MSG_ROUTING_NONE),
|
| + weak_factory_(this) {
|
| }
|
|
|
| -void EmbeddedWorkerInstance::RecordProcessId(
|
| - int process_id,
|
| +// static
|
| +void EmbeddedWorkerInstance::RunProcessAllocated(
|
| + base::WeakPtr<EmbeddedWorkerInstance> instance,
|
| + base::WeakPtr<ServiceWorkerContextCore> context,
|
| + scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
|
| + const EmbeddedWorkerInstance::StatusCallback& callback,
|
| ServiceWorkerStatusCode status,
|
| - int worker_devtools_agent_route_id) {
|
| + int process_id) {
|
| + if (!context) {
|
| + callback.Run(SERVICE_WORKER_ERROR_ABORT);
|
| + return;
|
| + }
|
| + if (!instance) {
|
| + context->process_manager()->ReleaseWorkerProcess(process_id);
|
| + callback.Run(SERVICE_WORKER_ERROR_ABORT);
|
| + return;
|
| + }
|
| + instance->ProcessAllocated(params.Pass(), callback, process_id, status);
|
| +}
|
| +
|
| +void EmbeddedWorkerInstance::ProcessAllocated(
|
| + scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
|
| + const StatusCallback& callback,
|
| + int process_id,
|
| + ServiceWorkerStatusCode status) {
|
| DCHECK_EQ(process_id_, -1);
|
| - DCHECK_EQ(worker_devtools_agent_route_id_, MSG_ROUTING_NONE);
|
| - if (status == SERVICE_WORKER_OK) {
|
| - process_id_ = process_id;
|
| - worker_devtools_agent_route_id_ = worker_devtools_agent_route_id;
|
| - } else {
|
| + if (status != SERVICE_WORKER_OK) {
|
| status_ = STOPPED;
|
| + callback.Run(status);
|
| + return;
|
| }
|
| + const int64 service_worker_version_id = params->service_worker_version_id;
|
| + process_id_ = process_id;
|
| + RegisterToWorkerDevToolsManager(
|
| + process_id,
|
| + context_.get(),
|
| + service_worker_version_id,
|
| + base::Bind(&EmbeddedWorkerInstance::SendStartWorker,
|
| + weak_factory_.GetWeakPtr(),
|
| + base::Passed(¶ms),
|
| + callback));
|
| +}
|
| +
|
| +void EmbeddedWorkerInstance::SendStartWorker(
|
| + scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
|
| + const StatusCallback& callback,
|
| + int worker_devtools_agent_route_id,
|
| + bool pause_on_start) {
|
| + worker_devtools_agent_route_id_ = worker_devtools_agent_route_id;
|
| + params->worker_devtools_agent_route_id = worker_devtools_agent_route_id;
|
| + params->pause_on_start = pause_on_start;
|
| + registry_->SendStartWorker(params.Pass(), callback, process_id_);
|
| }
|
|
|
| void EmbeddedWorkerInstance::OnScriptLoaded() {
|
| - // TODO(horo): Implement this.
|
| + if (worker_devtools_agent_route_id_ != MSG_ROUTING_NONE)
|
| + NotifyWorkerContextStarted(process_id_, worker_devtools_agent_route_id_);
|
| }
|
|
|
| void EmbeddedWorkerInstance::OnScriptLoadFailed() {
|
| @@ -117,6 +244,10 @@ void EmbeddedWorkerInstance::OnStarted(int thread_id) {
|
| }
|
|
|
| void EmbeddedWorkerInstance::OnStopped() {
|
| + if (worker_devtools_agent_route_id_ != MSG_ROUTING_NONE)
|
| + NotifyWorkerDestroyed(process_id_, worker_devtools_agent_route_id_);
|
| + if (context_)
|
| + context_->process_manager()->ReleaseWorkerProcess(process_id_);
|
| status_ = STOPPED;
|
| process_id_ = -1;
|
| thread_id_ = -1;
|
|
|