summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorclamy <clamy@chromium.org>2016-01-29 03:24:21 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-29 11:25:31 +0000
commitdcb0185ea06d638aa182385e7ee589b33830bb57 (patch)
treeeff68d126ce4fc36b5aa1678f1bacaf35b00b501 /content
parent194702589109b4f5374f131aa5f591965eb0f57b (diff)
downloadchromium_src-dcb0185ea06d638aa182385e7ee589b33830bb57.zip
chromium_src-dcb0185ea06d638aa182385e7ee589b33830bb57.tar.gz
chromium_src-dcb0185ea06d638aa182385e7ee589b33830bb57.tar.bz2
PlzNavigate: fix issue with navigation cancellation and ServiceWorker
This CL fixes a race condition happening when Plznavigate is enabled and a navigation is cancelled while being committed. The RenderFrame committing it creates a ServiceWorkerNetworkProvider based on an id given by the browser. When the ServiceWorkerDispatcherHost tries to retrieve the pre-created ServiceWorkerProviderHost, it has already been destroyed by the navigation cancellation. The SWDH considers this as bad message and kills the renderer. Now it just returns, as the navigation is about to be cancelled. Similarly, when the ServiceWorkerNetworkProvider is destroyed due to the navigation cancellation and had a pre-created ServiceWorkerDispatcherHost that was not registered (due to the condition described above), the SWDH will no longer consider it a bad message, and will just return early. BUG=475027 Review URL: https://codereview.chromium.org/1649763003 Cr-Commit-Position: refs/heads/master@{#372328}
Diffstat (limited to 'content')
-rw-r--r--content/browser/service_worker/service_worker_dispatcher_host.cc19
1 files changed, 13 insertions, 6 deletions
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index f8d80e0..78c54d1 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -748,11 +748,11 @@ void ServiceWorkerDispatcherHost::OnProviderCreated(
GetContext()->GetNavigationHandleCore(provider_id);
if (navigation_handle_core != nullptr)
provider_host = navigation_handle_core->RetrievePreCreatedHost();
- if (provider_host == nullptr) {
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_PROVIDER_CREATED_NO_HOST);
+
+ // If no host is found, the navigation has been cancelled in the meantime.
+ // Just return as the navigation will be stopped in the renderer as well.
+ if (provider_host == nullptr)
return;
- }
DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_WINDOW, provider_type);
provider_host->CompleteNavigationInitialized(render_process_id_, route_id,
this);
@@ -776,8 +776,15 @@ void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) {
if (!GetContext())
return;
if (!GetContext()->GetProviderHost(render_process_id_, provider_id)) {
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_PROVIDER_DESTROYED_NO_HOST);
+ // PlzNavigate: in some cancellation of navigation cases, it is possible
+ // for the pre-created hoist to have been destroyed before being claimed by
+ // the renderer. The provider is then destroyed in the renderer, and no
+ // matching host will be found.
+ if (!IsBrowserSideNavigationEnabled() ||
+ !ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id)) {
+ bad_message::ReceivedBadMessage(
+ this, bad_message::SWDH_PROVIDER_DESTROYED_NO_HOST);
+ }
return;
}
GetContext()->RemoveProviderHost(render_process_id_, provider_id);