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

Unified Diff: content/browser/service_worker/service_worker_provider_host.cc

Issue 855383006: ServiceWorker: Enqueue state change events until the worker thread gets ready (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix content_unittests Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/service_worker/service_worker_provider_host.cc
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc
index 12512a122eda99d33d3713f994ada6064a231219..2e698f1b14e531fc7d70c83e9c9fd984d7343460 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -46,16 +46,26 @@ void FocusOnUIThread(int render_process_id,
} // anonymous namespace
ServiceWorkerProviderHost::ServiceWorkerProviderHost(
- int render_process_id, int render_frame_id, int provider_id,
+ int render_process_id,
+ int render_frame_id,
+ int provider_id,
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerDispatcherHost* dispatcher_host)
: render_process_id_(render_process_id),
render_frame_id_(render_frame_id),
+ render_thread_id_(kInvalidEmbeddedWorkerThreadId),
provider_id_(provider_id),
context_(context),
dispatcher_host_(dispatcher_host),
allow_association_(true) {
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_);
+
+ // If |render_frame_id| is not MSG_ROUTING_NONE, this provider host works for
+ // the document context and its thread in the child process should be the main
+ // thread. For the worker context, the corresponding thread is notified when
+ // the worker context gets started via SetReadyToSend().
kinuko 2015/01/28 07:13:11 I think part of this comment should be probably in
nhiroki 2015/01/28 13:43:22 Done.
+ if (render_frame_id != MSG_ROUTING_NONE)
+ render_thread_id_ = kDocumentMainThreadId;
kinuko 2015/01/28 07:13:11 Doing the opposite might feel more natural /easier
nhiroki 2015/01/28 13:43:22 Done.
}
ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
@@ -119,8 +129,10 @@ void ServiceWorkerProviderHost::SetControllerVersionAttribute(
bool should_notify_controllerchange =
previous_version && version && version->skip_waiting();
- dispatcher_host_->Send(new ServiceWorkerMsg_SetControllerServiceWorker(
- kDocumentMainThreadId, provider_id(),
+ // SetController message should be sent only for the document context.
+ DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
+ Send(new ServiceWorkerMsg_SetControllerServiceWorker(
+ render_thread_id_, provider_id(),
CreateAndRegisterServiceWorkerHandle(version),
should_notify_controllerchange));
}
@@ -161,6 +173,7 @@ void ServiceWorkerProviderHost::AssociateRegistration(
}
void ServiceWorkerProviderHost::DisassociateRegistration() {
+ queued_events_.clear();
if (!associated_registration_.get())
return;
DecreaseProcessReference(associated_registration_->pattern());
@@ -168,10 +181,13 @@ void ServiceWorkerProviderHost::DisassociateRegistration() {
associated_registration_ = NULL;
SetControllerVersionAttribute(NULL);
- if (dispatcher_host_) {
- dispatcher_host_->Send(new ServiceWorkerMsg_DisassociateRegistration(
- kDocumentMainThreadId, provider_id()));
- }
+ if (!dispatcher_host_)
+ return;
+
+ // Disassociation message should be sent only for the document context.
+ DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
+ Send(new ServiceWorkerMsg_DisassociateRegistration(
+ render_thread_id_, provider_id()));
}
scoped_ptr<ServiceWorkerRequestHandler>
@@ -240,12 +256,11 @@ void ServiceWorkerProviderHost::PostMessage(
UpdateMessagePortsWithNewRoutes(sent_message_port_ids,
&new_routing_ids);
- dispatcher_host_->Send(
- new ServiceWorkerMsg_MessageToDocument(
- kDocumentMainThreadId, provider_id(),
- message,
- sent_message_port_ids,
- new_routing_ids));
+ Send(new ServiceWorkerMsg_MessageToDocument(
+ kDocumentMainThreadId, provider_id(),
+ message,
+ sent_message_port_ids,
+ new_routing_ids));
}
void ServiceWorkerProviderHost::Focus(const FocusCallback& callback) {
@@ -260,7 +275,7 @@ void ServiceWorkerProviderHost::Focus(const FocusCallback& callback) {
void ServiceWorkerProviderHost::GetClientInfo(
int embedded_worker_id,
int request_id) {
- dispatcher_host_->Send(new ServiceWorkerMsg_GetClientInfo(
+ Send(new ServiceWorkerMsg_GetClientInfo(
kDocumentMainThreadId, embedded_worker_id, request_id, provider_id()));
}
@@ -272,6 +287,8 @@ void ServiceWorkerProviderHost::AddScopedProcessReferenceToPattern(
void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() {
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_);
+ DCHECK_NE(MSG_ROUTING_NONE, render_frame_id_);
+ DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
for (const GURL& pattern : associated_patterns_)
DecreaseProcessReference(pattern);
@@ -279,13 +296,14 @@ void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() {
if (associated_registration_.get()) {
DecreaseProcessReference(associated_registration_->pattern());
if (dispatcher_host_) {
- dispatcher_host_->Send(new ServiceWorkerMsg_DisassociateRegistration(
- kDocumentMainThreadId, provider_id()));
+ Send(new ServiceWorkerMsg_DisassociateRegistration(
+ render_thread_id_, provider_id()));
}
}
render_process_id_ = ChildProcessHost::kInvalidUniqueID;
render_frame_id_ = MSG_ROUTING_NONE;
+ render_thread_id_ = kInvalidEmbeddedWorkerThreadId;
provider_id_ = kInvalidServiceWorkerProviderId;
dispatcher_host_ = nullptr;
}
@@ -297,9 +315,11 @@ void ServiceWorkerProviderHost::CompleteCrossSiteTransfer(
ServiceWorkerDispatcherHost* new_dispatcher_host) {
DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_);
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, new_process_id);
+ DCHECK_NE(MSG_ROUTING_NONE, new_frame_id);
render_process_id_ = new_process_id;
render_frame_id_ = new_frame_id;
+ render_thread_id_ = kDocumentMainThreadId;
provider_id_ = new_provider_id;
dispatcher_host_ = new_dispatcher_host;
@@ -310,8 +330,8 @@ void ServiceWorkerProviderHost::CompleteCrossSiteTransfer(
IncreaseProcessReference(associated_registration_->pattern());
SendAssociateRegistrationMessage();
if (dispatcher_host_ && associated_registration_->active_version()) {
- dispatcher_host_->Send(new ServiceWorkerMsg_SetControllerServiceWorker(
- kDocumentMainThreadId, provider_id(),
+ Send(new ServiceWorkerMsg_SetControllerServiceWorker(
+ render_thread_id_, provider_id(),
CreateAndRegisterServiceWorkerHandle(
associated_registration_->active_version()),
false /* shouldNotifyControllerChange */));
@@ -324,10 +344,13 @@ void ServiceWorkerProviderHost::SendUpdateFoundMessage(
if (!dispatcher_host_)
return; // Could be nullptr in some tests.
- // TODO(nhiroki): Queue the message if a receiver's thread is not ready yet
- // (http://crbug.com/437677).
- dispatcher_host_->Send(new ServiceWorkerMsg_UpdateFound(
- kDocumentMainThreadId, object_info));
+ if (!IsReadyToSend()) {
+ queued_events_.push_back(
+ base::Bind(&self::SendUpdateFoundMessage, AsWeakPtr(), object_info));
+ return;
+ }
+
+ Send(new ServiceWorkerMsg_UpdateFound(render_thread_id_, object_info));
}
void ServiceWorkerProviderHost::SendSetVersionAttributesMessage(
@@ -341,6 +364,16 @@ void ServiceWorkerProviderHost::SendSetVersionAttributesMessage(
if (!changed_mask.changed())
return;
+ if (!IsReadyToSend()) {
+ queued_events_.push_back(
+ base::Bind(&self::SendSetVersionAttributesMessage,
+ AsWeakPtr(), registration_handle_id, changed_mask,
+ make_scoped_refptr(installing_version),
+ make_scoped_refptr(waiting_version),
+ make_scoped_refptr(active_version)));
+ return;
+ }
+
ServiceWorkerVersionAttributes attrs;
if (changed_mask.installing_changed())
attrs.installing = CreateAndRegisterServiceWorkerHandle(installing_version);
@@ -349,10 +382,8 @@ void ServiceWorkerProviderHost::SendSetVersionAttributesMessage(
if (changed_mask.active_changed())
attrs.active = CreateAndRegisterServiceWorkerHandle(active_version);
- // TODO(nhiroki): Queue the message if a receiver's thread is not ready yet
- // (http://crbug.com/437677).
- dispatcher_host_->Send(new ServiceWorkerMsg_SetVersionAttributes(
- kDocumentMainThreadId, provider_id_, registration_handle_id,
+ Send(new ServiceWorkerMsg_SetVersionAttributes(
+ render_thread_id_, provider_id_, registration_handle_id,
changed_mask.changed(), attrs));
}
@@ -362,10 +393,24 @@ void ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage(
if (!dispatcher_host_)
return;
- // TODO(nhiroki): Queue the message if a receiver's thread is not ready yet
- // (http://crbug.com/437677).
- dispatcher_host_->Send(new ServiceWorkerMsg_ServiceWorkerStateChanged(
- kDocumentMainThreadId, worker_handle_id, state));
+ if (!IsReadyToSend()) {
+ queued_events_.push_back(
+ base::Bind(&self::SendServiceWorkerStateChangedMessage,
+ AsWeakPtr(), worker_handle_id, state));
+ return;
+ }
+
+ Send(new ServiceWorkerMsg_ServiceWorkerStateChanged(
+ render_thread_id_, worker_handle_id, state));
+}
+
+void ServiceWorkerProviderHost::SetReadyToSend(int render_thread_id) {
+ DCHECK(!IsReadyToSend());
+ render_thread_id_ = render_thread_id;
+
+ for (const auto& event : queued_events_)
+ event.Run();
+ queued_events_.clear();
}
void ServiceWorkerProviderHost::SendAssociateRegistrationMessage() {
@@ -384,8 +429,10 @@ void ServiceWorkerProviderHost::SendAssociateRegistrationMessage() {
attrs.active = CreateAndRegisterServiceWorkerHandle(
associated_registration_->active_version());
+ // Association message should be sent only for the document context.
+ DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
dispatcher_host_->Send(new ServiceWorkerMsg_AssociateRegistration(
- kDocumentMainThreadId, provider_id(), handle->GetObjectInfo(), attrs));
+ render_thread_id_, provider_id(), handle->GetObjectInfo(), attrs));
}
void ServiceWorkerProviderHost::IncreaseProcessReference(
@@ -404,8 +451,18 @@ void ServiceWorkerProviderHost::DecreaseProcessReference(
}
}
+bool ServiceWorkerProviderHost::IsReadyToSend() const {
+ return render_thread_id_ != kInvalidEmbeddedWorkerThreadId;
+}
+
bool ServiceWorkerProviderHost::IsContextAlive() {
return context_ != NULL;
}
+void ServiceWorkerProviderHost::Send(IPC::Message* message) const {
+ DCHECK(dispatcher_host_);
+ DCHECK(IsReadyToSend());
+ dispatcher_host_->Send(message);
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698