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

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: address falken@'s comments 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..c5f9b16ef4a6d94b5beac935992e2af8a2e0875f 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -46,16 +46,23 @@ 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_(kDocumentMainThreadId),
provider_id_(provider_id),
context_(context),
dispatcher_host_(dispatcher_host),
allow_association_(true) {
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_);
+ if (render_frame_id == MSG_ROUTING_NONE) {
+ // Actual thread id is set when the worker context gets started.
+ render_thread_id_ = kInvalidEmbeddedWorkerThreadId;
+ }
}
ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
@@ -119,8 +126,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 +170,7 @@ void ServiceWorkerProviderHost::AssociateRegistration(
}
void ServiceWorkerProviderHost::DisassociateRegistration() {
+ queued_events_.clear();
if (!associated_registration_.get())
return;
DecreaseProcessReference(associated_registration_->pattern());
@@ -168,10 +178,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 +253,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 +272,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 +284,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 +293,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 +312,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 +327,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 +341,14 @@ 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 (!IsReadyToSendMessages()) {
+ queued_events_.push_back(
+ base::Bind(&ServiceWorkerProviderHost::SendUpdateFoundMessage,
+ AsWeakPtr(), object_info));
+ return;
+ }
+
+ Send(new ServiceWorkerMsg_UpdateFound(render_thread_id_, object_info));
}
void ServiceWorkerProviderHost::SendSetVersionAttributesMessage(
@@ -341,6 +362,16 @@ void ServiceWorkerProviderHost::SendSetVersionAttributesMessage(
if (!changed_mask.changed())
return;
+ if (!IsReadyToSendMessages()) {
+ queued_events_.push_back(
+ base::Bind(&ServiceWorkerProviderHost::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 +380,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 +391,25 @@ 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 (!IsReadyToSendMessages()) {
+ queued_events_.push_back(base::Bind(
+ &ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage,
+ AsWeakPtr(), worker_handle_id, state));
+ return;
+ }
+
+ Send(new ServiceWorkerMsg_ServiceWorkerStateChanged(
+ render_thread_id_, worker_handle_id, state));
+}
+
+void ServiceWorkerProviderHost::SetReadyToSendMessagesToWorker(
+ int render_thread_id) {
+ DCHECK(!IsReadyToSendMessages());
+ render_thread_id_ = render_thread_id;
+
+ for (const auto& event : queued_events_)
+ event.Run();
+ queued_events_.clear();
}
void ServiceWorkerProviderHost::SendAssociateRegistrationMessage() {
@@ -384,8 +428,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 +450,18 @@ void ServiceWorkerProviderHost::DecreaseProcessReference(
}
}
+bool ServiceWorkerProviderHost::IsReadyToSendMessages() const {
+ return render_thread_id_ != kInvalidEmbeddedWorkerThreadId;
+}
+
bool ServiceWorkerProviderHost::IsContextAlive() {
return context_ != NULL;
}
+void ServiceWorkerProviderHost::Send(IPC::Message* message) const {
+ DCHECK(dispatcher_host_);
+ DCHECK(IsReadyToSendMessages());
+ dispatcher_host_->Send(message);
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698