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 891fc227989ca9cc61b708cd05c2b0be30ed8340..2806f12aa2b4af875b7c9aa1059a14ad100c0d13 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,11 +25,75 @@ 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, |
+ EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier( |
+ 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 (status_ == STARTING || status_ == RUNNING) |
Stop(); |
+ 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_); |
} |
@@ -32,15 +102,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() { |
@@ -77,32 +160,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() { |
@@ -119,6 +246,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; |