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

Unified Diff: content/browser/loader/resource_dispatcher_host_impl.cc

Issue 1542743002: [RDHI] Refactored blocked_loaders_map_ to key by render frame route id (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: New, simpler API (default recurses frame tree) Created 4 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/loader/resource_dispatcher_host_impl.cc
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index fa7ede3fdb7db7056403e35e6fc5398bcb69fe6e..f6da80512ada59ca45e0f81d50c7da167923d79e 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -39,6 +39,7 @@
#include "content/browser/download/save_file_manager.h"
#include "content/browser/download/save_file_resource_handler.h"
#include "content/browser/fileapi/chrome_blob_storage_context.h"
+#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/loader/async_resource_handler.h"
@@ -466,8 +467,79 @@ void RecordAbortRapporOnUI(const GURL& url,
GetContentClient()->browser()->RecordURLMetric("Net.ErrAborted.Slow", url);
}
+// The following functions simplify code paths where the UI thread notifies the
+// ResourceDispatcherHostImpl of information pertaining to loading behavior of
+// frame hosts.
+void NotifyForRouteOnIO(
+ base::Callback<void(ResourceDispatcherHostImpl*,
+ const GlobalFrameRoutingId&)> frame_callback,
+ const GlobalFrameRoutingId& global_routing_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
+ if (rdh)
+ frame_callback.Run(rdh, global_routing_id);
+}
+
+void NotifyForRoute(
+ const GlobalFrameRoutingId& global_routing_id,
+ base::Callback<void(ResourceDispatcherHostImpl*,
+ const GlobalFrameRoutingId&)> frame_callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&NotifyForRouteOnIO, frame_callback, global_routing_id));
+}
+
+void NotifyForEachFrameOnIO(
Randy Smith (Not in Mondays) 2016/02/01 21:19:20 nitty nit, suggestion: The name of this function i
Charlie Harrison 2016/02/01 23:05:39 Changed it to "NotifyForRouteSetOnIO", to better p
+ base::Callback<void(ResourceDispatcherHostImpl*,
+ const GlobalFrameRoutingId&)> frame_callback,
+ scoped_ptr<std::set<GlobalFrameRoutingId>> routing_ids) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ for (const auto& routing_id : *routing_ids)
+ NotifyForRouteOnIO(frame_callback, routing_id);
+}
+
+void NotifyForEachFrame(
Randy Smith (Not in Mondays) 2016/02/01 21:19:20 Same as above.
Charlie Harrison 2016/02/01 23:05:39 I prefer to leave this one as is. I can't really t
Randy Smith (Not in Mondays) 2016/02/02 20:47:06 Yeah, looking at it more closely, this is fine. O
+ RenderFrameHost* root_frame_host,
+ base::Callback<void(ResourceDispatcherHostImpl*,
+ const GlobalFrameRoutingId&)> frame_callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ FrameTree* frame_tree = static_cast<RenderFrameHostImpl*>(root_frame_host)
+ ->frame_tree_node()
+ ->frame_tree();
+ DCHECK_EQ(root_frame_host, frame_tree->GetMainFrame());
+ scoped_ptr<std::set<GlobalFrameRoutingId>> routing_ids(
+ new std::set<GlobalFrameRoutingId>());
+ for (FrameTreeNode* node : frame_tree->Nodes()) {
+ RenderFrameHostImpl* frame_host = node->current_frame_host();
+ RenderFrameHostImpl* pending_frame_host =
+ IsBrowserSideNavigationEnabled()
+ ? node->render_manager()->speculative_frame_host()
+ : node->render_manager()->pending_frame_host();
+ if (frame_host)
+ routing_ids->insert(frame_host->GetGlobalFrameRoutingId());
+ if (pending_frame_host)
+ routing_ids->insert(pending_frame_host->GetGlobalFrameRoutingId());
+ }
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&NotifyForEachFrameOnIO, frame_callback,
+ base::Passed(std::move(routing_ids))));
+}
+
} // namespace
+LoaderIOThreadNotifier::LoaderIOThreadNotifier(WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+
+LoaderIOThreadNotifier::~LoaderIOThreadNotifier() {}
+
+void LoaderIOThreadNotifier::RenderFrameDeleted(
+ RenderFrameHost* render_frame_host) {
+ NotifyForRoute(static_cast<RenderFrameHostImpl*>(render_frame_host)
+ ->GetGlobalFrameRoutingId(),
+ base::Bind(&ResourceDispatcherHostImpl::OnRenderFrameDeleted));
Randy Smith (Not in Mondays) 2016/02/01 21:19:20 nit, suggestion: I'm inclined to think it's a clea
Charlie Harrison 2016/02/01 23:05:39 I implemented this suggestion.
+}
+
// static
ResourceDispatcherHost* ResourceDispatcherHost::Get() {
return g_resource_dispatcher_host;
@@ -534,6 +606,42 @@ ResourceDispatcherHostImpl* ResourceDispatcherHostImpl::Get() {
return g_resource_dispatcher_host;
}
+// static
+void ResourceDispatcherHostImpl::ResumeBlockedRequestsForRouteOnUI(
+ const GlobalFrameRoutingId& global_routing_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ NotifyForRoute(
+ global_routing_id,
+ base::Bind(&ResourceDispatcherHostImpl::ResumeBlockedRequestsForRoute));
+}
+
+// static
+void ResourceDispatcherHostImpl::BlockRequestsForFrames(
+ RenderFrameHost* root_frame_host) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ NotifyForEachFrame(
+ root_frame_host,
+ base::Bind(&ResourceDispatcherHostImpl::BlockRequestsForRoute));
+}
+
+// static
+void ResourceDispatcherHostImpl::ResumeBlockedRequestsForFrames(
+ RenderFrameHost* root_frame_host) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ NotifyForEachFrame(
+ root_frame_host,
+ base::Bind(&ResourceDispatcherHostImpl::ResumeBlockedRequestsForRoute));
+}
+
+// static
+void ResourceDispatcherHostImpl::CancelBlockedRequestsForFrames(
+ RenderFrameHostImpl* root_frame_host) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ NotifyForEachFrame(
+ root_frame_host,
+ base::Bind(&ResourceDispatcherHostImpl::CancelBlockedRequestsForRoute));
+}
+
void ResourceDispatcherHostImpl::SetDelegate(
ResourceDispatcherHostDelegate* delegate) {
delegate_ = delegate;
@@ -1090,15 +1198,15 @@ void ResourceDispatcherHostImpl::OnShutdown() {
// Note that we have to do this in 2 passes as we cannot call
// CancelBlockedRequestsForRoute while iterating over
// blocked_loaders_map_, as it modifies it.
- std::set<GlobalRoutingID> ids;
+ std::set<GlobalFrameRoutingId> ids;
for (const auto& blocked_loaders : blocked_loaders_map_) {
- std::pair<std::set<GlobalRoutingID>::iterator, bool> result =
+ std::pair<std::set<GlobalFrameRoutingId>::iterator, bool> result =
ids.insert(blocked_loaders.first);
// We should not have duplicates.
DCHECK(result.second);
}
for (const auto& routing_id : ids) {
- CancelBlockedRequestsForRoute(routing_id.child_id, routing_id.route_id);
+ CancelBlockedRequestsForRoute(routing_id);
}
scheduler_.reset();
@@ -1194,11 +1302,11 @@ void ResourceDispatcherHostImpl::UpdateRequestForTransfer(
const ResourceHostMsg_Request& request_data,
LoaderMap::iterator iter) {
ResourceRequestInfoImpl* info = iter->second->GetRequestInfo();
- GlobalRoutingID old_routing_id(
- request_data.transferred_request_child_id, info->GetRouteID());
+ GlobalFrameRoutingId old_routing_id(request_data.transferred_request_child_id,
+ info->GetRenderFrameID());
GlobalRequestID old_request_id(request_data.transferred_request_child_id,
request_data.transferred_request_request_id);
- GlobalRoutingID new_routing_id(child_id, route_id);
+ GlobalFrameRoutingId new_routing_id(child_id, request_data.render_frame_id);
GlobalRequestID new_request_id(child_id, request_id);
// Clear out data that depends on |info| before updating it.
@@ -1761,6 +1869,11 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
std::string()); // original_headers
}
+void ResourceDispatcherHostImpl::OnRenderFrameDeleted(
+ const GlobalFrameRoutingId& global_routing_id) {
+ CancelRequestsForRoute(global_routing_id);
Randy Smith (Not in Mondays) 2016/02/01 21:19:20 Alternatively to my other suggestion, just make Lo
Charlie Harrison 2016/02/01 23:05:39 I implemented your previous suggestion.
+}
+
void ResourceDispatcherHostImpl::OnRenderViewHostCreated(int child_id,
int route_id,
bool is_visible,
@@ -1768,11 +1881,9 @@ void ResourceDispatcherHostImpl::OnRenderViewHostCreated(int child_id,
scheduler_->OnClientCreated(child_id, route_id, is_visible, is_audible);
}
-void ResourceDispatcherHostImpl::OnRenderViewHostDeleted(
- int child_id,
- int route_id) {
+void ResourceDispatcherHostImpl::OnRenderViewHostDeleted(int child_id,
+ int route_id) {
scheduler_->OnClientDeleted(child_id, route_id);
- CancelRequestsForRoute(child_id, route_id);
}
void ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading(int child_id,
@@ -1881,18 +1992,23 @@ void ResourceDispatcherHostImpl::ResumeDeferredNavigation(
// for downloads and detachable resources, which belong to the browser process
// even if initiated via a renderer.
void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) {
- CancelRequestsForRoute(child_id, -1 /* cancel all */);
+ CancelRequestsForRoute(
+ GlobalFrameRoutingId(child_id, MSG_ROUTING_NONE /* cancel all */));
registered_temp_files_.erase(child_id);
}
-void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id,
- int route_id) {
+void ResourceDispatcherHostImpl::CancelRequestsForRoute(
+ const GlobalFrameRoutingId& global_routing_id) {
// Since pending_requests_ is a map, we first build up a list of all of the
// matching requests to be cancelled, and then we cancel them. Since there
// may be more than one request to cancel, we cannot simply hold onto the map
// iterators found in the first loop.
// Find the global ID of all matching elements.
+ int child_id = global_routing_id.child_id;
+ int route_id = global_routing_id.frame_routing_id;
+ bool cancel_all_routes = (route_id == MSG_ROUTING_NONE);
+
bool any_requests_transferring = false;
std::vector<GlobalRequestID> matching_requests;
for (const auto& loader : pending_loaders_) {
@@ -1910,7 +2026,7 @@ void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id,
info->detachable_handler()->Detach();
} else if (!info->IsDownload() && !info->is_stream() &&
!IsTransferredNavigation(id) &&
- (route_id == -1 || route_id == info->GetRouteID())) {
+ (cancel_all_routes || route_id == info->GetRenderFrameID())) {
matching_requests.push_back(id);
}
}
@@ -1940,23 +2056,23 @@ void ResourceDispatcherHostImpl::CancelRequestsForRoute(int child_id,
return;
// Now deal with blocked requests if any.
- if (route_id != -1) {
- if (blocked_loaders_map_.find(GlobalRoutingID(child_id, route_id)) !=
+ if (!cancel_all_routes) {
+ if (blocked_loaders_map_.find(global_routing_id) !=
blocked_loaders_map_.end()) {
- CancelBlockedRequestsForRoute(child_id, route_id);
+ CancelBlockedRequestsForRoute(global_routing_id);
}
} else {
- // We have to do all render views for the process |child_id|.
+ // We have to do all render frames for the process |child_id|.
// Note that we have to do this in 2 passes as we cannot call
// CancelBlockedRequestsForRoute while iterating over
- // blocked_loaders_map_, as it modifies it.
- std::set<int> route_ids;
+ // blocked_loaders_map_, as blocking requests modifies the map.
+ std::set<GlobalFrameRoutingId> routing_ids;
for (const auto& blocked_loaders : blocked_loaders_map_) {
if (blocked_loaders.first.child_id == child_id)
- route_ids.insert(blocked_loaders.first.route_id);
+ routing_ids.insert(blocked_loaders.first);
}
- for (int route_id : route_ids) {
- CancelBlockedRequestsForRoute(child_id, route_id);
+ for (const GlobalFrameRoutingId& route_id : routing_ids) {
+ CancelBlockedRequestsForRoute(route_id);
}
}
}
@@ -2303,7 +2419,7 @@ void ResourceDispatcherHostImpl::BeginRequestInternal(
scoped_ptr<ResourceLoader> loader(
new ResourceLoader(std::move(request), std::move(handler), this));
- GlobalRoutingID id(info->GetGlobalRoutingID());
+ GlobalFrameRoutingId id(info->GetChildID(), info->GetRenderFrameID());
BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(id);
if (iter != blocked_loaders_map_.end()) {
// The request should be blocked.
@@ -2427,31 +2543,31 @@ void ResourceDispatcherHostImpl::UpdateLoadInfo() {
base::Passed(&info_map)));
}
-void ResourceDispatcherHostImpl::BlockRequestsForRoute(int child_id,
- int route_id) {
+void ResourceDispatcherHostImpl::BlockRequestsForRoute(
+ const GlobalFrameRoutingId& global_routing_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- GlobalRoutingID key(child_id, route_id);
- DCHECK(blocked_loaders_map_.find(key) == blocked_loaders_map_.end()) <<
- "BlockRequestsForRoute called multiple time for the same RVH";
- blocked_loaders_map_[key] = make_scoped_ptr(new BlockedLoadersList());
+ DCHECK(blocked_loaders_map_.find(global_routing_id) ==
+ blocked_loaders_map_.end())
+ << "BlockRequestsForRoute called multiple time for the same RFH";
+ blocked_loaders_map_[global_routing_id] =
+ make_scoped_ptr(new BlockedLoadersList());
}
-void ResourceDispatcherHostImpl::ResumeBlockedRequestsForRoute(int child_id,
- int route_id) {
- ProcessBlockedRequestsForRoute(child_id, route_id, false);
+void ResourceDispatcherHostImpl::ResumeBlockedRequestsForRoute(
+ const GlobalFrameRoutingId& global_routing_id) {
+ ProcessBlockedRequestsForRoute(global_routing_id, false);
}
-void ResourceDispatcherHostImpl::CancelBlockedRequestsForRoute(int child_id,
- int route_id) {
- ProcessBlockedRequestsForRoute(child_id, route_id, true);
+void ResourceDispatcherHostImpl::CancelBlockedRequestsForRoute(
+ const GlobalFrameRoutingId& global_routing_id) {
+ ProcessBlockedRequestsForRoute(global_routing_id, true);
}
void ResourceDispatcherHostImpl::ProcessBlockedRequestsForRoute(
- int child_id,
- int route_id,
+ const GlobalFrameRoutingId& global_routing_id,
bool cancel_requests) {
- BlockedLoadersMap::iterator iter = blocked_loaders_map_.find(
- GlobalRoutingID(child_id, route_id));
+ BlockedLoadersMap::iterator iter =
+ blocked_loaders_map_.find(global_routing_id);
if (iter == blocked_loaders_map_.end()) {
// It's possible to reach here if the renderer crashed while an interstitial
// page was showing.

Powered by Google App Engine
This is Rietveld 408576698