| Index: trunk/src/content/browser/frame_host/render_frame_host_manager.cc
|
| ===================================================================
|
| --- trunk/src/content/browser/frame_host/render_frame_host_manager.cc (revision 263366)
|
| +++ trunk/src/content/browser/frame_host/render_frame_host_manager.cc (working copy)
|
| @@ -20,7 +20,6 @@
|
| #include "content/browser/frame_host/navigator.h"
|
| #include "content/browser/frame_host/render_frame_host_factory.h"
|
| #include "content/browser/frame_host/render_frame_host_impl.h"
|
| -#include "content/browser/frame_host/render_frame_proxy_host.h"
|
| #include "content/browser/renderer_host/render_process_host_impl.h"
|
| #include "content/browser/renderer_host/render_view_host_factory.h"
|
| #include "content/browser/renderer_host/render_view_host_impl.h"
|
| @@ -90,9 +89,11 @@
|
| // We should always have a current RenderFrameHost except in some tests.
|
| render_frame_host_.reset();
|
|
|
| + // TODO(creis): Now that we aren't using Shutdown, make RenderFrameHostMap
|
| + // use scoped_ptrs.
|
| // Delete any swapped out RenderFrameHosts.
|
| - for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
|
| - iter != proxy_hosts_.end();
|
| + for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin();
|
| + iter != swapped_out_hosts_.end();
|
| ++iter) {
|
| delete iter->second;
|
| }
|
| @@ -108,11 +109,9 @@
|
| if (!site_instance)
|
| site_instance = SiteInstance::Create(browser_context);
|
|
|
| - render_frame_host_ = CreateRenderFrameHost(site_instance,
|
| - view_routing_id,
|
| - frame_routing_id,
|
| - false,
|
| - delegate_->IsHidden());
|
| + render_frame_host_ = make_scoped_ptr(
|
| + CreateRenderFrameHost(site_instance, view_routing_id, frame_routing_id,
|
| + false, delegate_->IsHidden()));
|
|
|
| // Keep track of renderer processes as they start to shut down or are
|
| // crashed/killed.
|
| @@ -448,8 +447,8 @@
|
| // TODO(creis): Take in RenderFrameHost instead, since frames can have openers.
|
| void RenderFrameHostManager::DidDisownOpener(RenderViewHost* render_view_host) {
|
| // Notify all swapped out hosts, including the pending RVH.
|
| - for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
|
| - iter != proxy_hosts_.end();
|
| + for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin();
|
| + iter != swapped_out_hosts_.end();
|
| ++iter) {
|
| DCHECK_NE(iter->second->GetSiteInstance(),
|
| current_frame_host()->GetSiteInstance());
|
| @@ -463,8 +462,8 @@
|
| // swap them back in while the process is exiting. Start by finding them,
|
| // since there could be more than one.
|
| std::list<int> ids_to_remove;
|
| - for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
|
| - iter != proxy_hosts_.end();
|
| + for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin();
|
| + iter != swapped_out_hosts_.end();
|
| ++iter) {
|
| if (iter->second->GetProcess() == render_process_host)
|
| ids_to_remove.push_back(iter->first);
|
| @@ -472,8 +471,8 @@
|
|
|
| // Now delete them.
|
| while (!ids_to_remove.empty()) {
|
| - delete proxy_hosts_[ids_to_remove.back()];
|
| - proxy_hosts_.erase(ids_to_remove.back());
|
| + delete swapped_out_hosts_[ids_to_remove.back()];
|
| + swapped_out_hosts_.erase(ids_to_remove.back());
|
| ids_to_remove.pop_back();
|
| }
|
| }
|
| @@ -549,36 +548,34 @@
|
| }
|
| }
|
|
|
| -bool RenderFrameHostManager::ClearProxiesInSiteInstance(
|
| +bool RenderFrameHostManager::ClearSwappedOutRFHsInSiteInstance(
|
| int32 site_instance_id,
|
| FrameTreeNode* node) {
|
| - RenderFrameProxyHostMap::iterator iter =
|
| - node->render_manager()->proxy_hosts_.find(site_instance_id);
|
| - if (iter != node->render_manager()->proxy_hosts_.end()) {
|
| - RenderFrameProxyHost* proxy = iter->second;
|
| + RenderFrameHostMap::iterator iter =
|
| + node->render_manager()->swapped_out_hosts_.find(site_instance_id);
|
| + if (iter != node->render_manager()->swapped_out_hosts_.end()) {
|
| + RenderFrameHostImpl* swapped_out_rfh = iter->second;
|
| // If the RVH is pending swap out, it needs to switch state to
|
| // pending shutdown. Otherwise it is deleted.
|
| - if (proxy->render_view_host()->rvh_state() ==
|
| + if (swapped_out_rfh->render_view_host()->rvh_state() ==
|
| RenderViewHostImpl::STATE_PENDING_SWAP_OUT) {
|
| - scoped_ptr<RenderFrameHostImpl> swapped_out_rfh = proxy->PassFrameHost();
|
| -
|
| swapped_out_rfh->SetPendingShutdown(base::Bind(
|
| &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance,
|
| node->render_manager()->weak_factory_.GetWeakPtr(),
|
| site_instance_id,
|
| - swapped_out_rfh.get()));
|
| + swapped_out_rfh));
|
| RFHPendingDeleteMap::iterator pending_delete_iter =
|
| node->render_manager()->pending_delete_hosts_.find(site_instance_id);
|
| if (pending_delete_iter ==
|
| node->render_manager()->pending_delete_hosts_.end() ||
|
| - pending_delete_iter->second.get() != swapped_out_rfh) {
|
| + pending_delete_iter->second.get() != iter->second) {
|
| node->render_manager()->pending_delete_hosts_[site_instance_id] =
|
| - linked_ptr<RenderFrameHostImpl>(swapped_out_rfh.release());
|
| + linked_ptr<RenderFrameHostImpl>(swapped_out_rfh);
|
| }
|
| } else {
|
| - delete proxy;
|
| + delete swapped_out_rfh;
|
| }
|
| - node->render_manager()->proxy_hosts_.erase(site_instance_id);
|
| + node->render_manager()->swapped_out_hosts_.erase(site_instance_id);
|
| }
|
|
|
| return true;
|
| @@ -836,7 +833,7 @@
|
| return current_instance->GetRelatedSiteInstance(dest_url);
|
| }
|
|
|
| -scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost(
|
| +RenderFrameHostImpl* RenderFrameHostManager::CreateRenderFrameHost(
|
| SiteInstance* site_instance,
|
| int view_routing_id,
|
| int frame_routing_id,
|
| @@ -865,15 +862,16 @@
|
| }
|
| }
|
|
|
| + // TODO(creis): Make render_frame_host a scoped_ptr.
|
| // TODO(creis): Pass hidden to RFH.
|
| - scoped_ptr<RenderFrameHostImpl> render_frame_host =
|
| - make_scoped_ptr(RenderFrameHostFactory::Create(render_view_host,
|
| - render_frame_delegate_,
|
| - frame_tree,
|
| - frame_tree_node_,
|
| - frame_routing_id,
|
| - swapped_out).release());
|
| - return render_frame_host.Pass();
|
| + RenderFrameHostImpl* render_frame_host =
|
| + RenderFrameHostFactory::Create(render_view_host,
|
| + render_frame_delegate_,
|
| + frame_tree,
|
| + frame_tree_node_,
|
| + frame_routing_id,
|
| + swapped_out).release();
|
| + return render_frame_host;
|
| }
|
|
|
| int RenderFrameHostManager::CreateRenderFrame(
|
| @@ -884,9 +882,6 @@
|
| CHECK(instance);
|
| DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden.
|
|
|
| - scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
|
| - int routing_id = MSG_ROUTING_NONE;
|
| -
|
| // We are creating a pending or swapped out RFH here. We should never create
|
| // it in the same SiteInstance as our current RFH.
|
| CHECK_NE(render_frame_host_->GetSiteInstance(), instance);
|
| @@ -894,22 +889,17 @@
|
| // Check if we've already created an RFH for this SiteInstance. If so, try
|
| // to re-use the existing one, which has already been initialized. We'll
|
| // remove it from the list of swapped out hosts if it commits.
|
| - RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
|
| + RenderFrameHostImpl* new_render_frame_host =
|
| + GetSwappedOutRenderFrameHost(instance);
|
|
|
| FrameTreeNode* parent_node = NULL;
|
| if (frame_tree_node_)
|
| parent_node = frame_tree_node_->parent();
|
|
|
| - if (proxy) {
|
| - routing_id = proxy->render_view_host()->GetRoutingID();
|
| - // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
|
| + if (new_render_frame_host) {
|
| // Prevent the process from exiting while we're trying to use it.
|
| if (!swapped_out) {
|
| - new_render_frame_host = proxy->PassFrameHost();
|
| new_render_frame_host->GetProcess()->AddPendingView();
|
| -
|
| - proxy_hosts_.erase(instance->GetId());
|
| - delete proxy;
|
| } else {
|
| // Detect if this is a cross-process child frame that is navigating
|
| // back to the same SiteInstance as its parent.
|
| @@ -922,20 +912,21 @@
|
| }
|
| } else {
|
| // Create a new RenderFrameHost if we don't find an existing one.
|
| - new_render_frame_host = CreateRenderFrameHost(
|
| - instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden);
|
| - RenderViewHostImpl* render_view_host =
|
| - new_render_frame_host->render_view_host();
|
| + // TODO(creis): Make new_render_frame_host a scoped_ptr.
|
| + new_render_frame_host = CreateRenderFrameHost(instance, MSG_ROUTING_NONE,
|
| + MSG_ROUTING_NONE, swapped_out,
|
| + hidden);
|
|
|
| - // Prevent the process from exiting while we're trying to navigate in it.
|
| - // Otherwise, if the new RFH is swapped out already, store it.
|
| - if (!swapped_out) {
|
| - new_render_frame_host->GetProcess()->AddPendingView();
|
| + // If the new RFH is swapped out already, store it. Otherwise prevent the
|
| + // process from exiting while we're trying to navigate in it.
|
| + if (swapped_out) {
|
| + swapped_out_hosts_[instance->GetId()] = new_render_frame_host;
|
| } else {
|
| - proxy_hosts_[instance->GetId()] = new RenderFrameProxyHost(
|
| - new_render_frame_host.Pass());
|
| + new_render_frame_host->GetProcess()->AddPendingView();
|
| }
|
|
|
| + RenderViewHostImpl* render_view_host =
|
| + new_render_frame_host->render_view_host();
|
| bool success = InitRenderView(render_view_host, opener_route_id);
|
| if (success && frame_tree_node_->IsMainFrame()) {
|
| // Don't show the main frame's view until we get a DidNavigate from it.
|
| @@ -943,14 +934,13 @@
|
| } else if (!swapped_out && pending_render_frame_host_) {
|
| CancelPending();
|
| }
|
| - routing_id = render_view_host->GetRoutingID();
|
| }
|
|
|
| // Use this as our new pending RFH if it isn't swapped out.
|
| if (!swapped_out)
|
| - pending_render_frame_host_ = new_render_frame_host.Pass();
|
| + pending_render_frame_host_.reset(new_render_frame_host);
|
|
|
| - return routing_id;
|
| + return new_render_frame_host->render_view_host()->GetRoutingID();
|
| }
|
|
|
| bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host,
|
| @@ -1027,8 +1017,7 @@
|
|
|
| // Swap in the pending frame and make it active. Also ensure the FrameTree
|
| // stays in sync.
|
| - scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
|
| - render_frame_host_.Pass();
|
| + RenderFrameHostImpl* old_render_frame_host = render_frame_host_.release();
|
| render_frame_host_ = pending_render_frame_host_.Pass();
|
| if (is_main_frame)
|
| render_frame_host_->render_view_host()->AttachToFrameTree();
|
| @@ -1057,7 +1046,7 @@
|
| &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance,
|
| weak_factory_.GetWeakPtr(),
|
| old_site_instance_id,
|
| - old_render_frame_host.get()));
|
| + old_render_frame_host));
|
| } else {
|
| // TODO(creis): We'll need to set this back to false if we navigate back.
|
| old_render_frame_host->set_swapped_out(true);
|
| @@ -1085,45 +1074,47 @@
|
| render_frame_host_->render_view_host());
|
| }
|
|
|
| - // If the old RFH is not live, just return as there is no work to do.
|
| - if (!old_render_frame_host->render_view_host()->IsRenderViewLive()) {
|
| - return;
|
| - }
|
| + // If the pending frame was on the swapped out list, we can remove it.
|
| + swapped_out_hosts_.erase(render_frame_host_->GetSiteInstance()->GetId());
|
|
|
| - // If the old RFH is live, we are swapping it out and should keep track of
|
| - // it in case we navigate back to it, or it is waiting for the unload event
|
| - // to execute in the background.
|
| - // TODO(creis): Swap out the subframe in --site-per-process.
|
| - if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess))
|
| - DCHECK(old_render_frame_host->is_swapped_out() ||
|
| - !RenderViewHostImpl::IsRVHStateActive(
|
| - old_render_frame_host->render_view_host()->rvh_state()));
|
| - // Temp fix for http://crbug.com/90867 until we do a better cleanup to make
|
| - // sure we don't get different rvh instances for the same site instance
|
| - // in the same rvhmgr.
|
| - // TODO(creis): Clean this up.
|
| - RenderFrameProxyHostMap::iterator iter =
|
| - proxy_hosts_.find(old_site_instance_id);
|
| - if (iter != proxy_hosts_.end() &&
|
| - iter->second->render_frame_host() != old_render_frame_host) {
|
| - // Delete the proxy that will be replaced in the map to avoid a leak.
|
| - delete iter->second;
|
| - }
|
| -
|
| - // If the RenderViewHost backing the RenderFrameHost is pending shutdown,
|
| - // the RenderFrameHost should be put in the map of RenderFrameHosts pending
|
| - // shutdown. Otherwise, it is stored in the map of proxy hosts.
|
| - if (old_render_frame_host->render_view_host()->rvh_state() ==
|
| - RenderViewHostImpl::STATE_PENDING_SHUTDOWN) {
|
| - proxy_hosts_.erase(old_site_instance_id);
|
| - RFHPendingDeleteMap::iterator pending_delete_iter =
|
| - pending_delete_hosts_.find(old_site_instance_id);
|
| - if (pending_delete_iter == pending_delete_hosts_.end() ||
|
| - pending_delete_iter->second.get() != old_render_frame_host) {
|
| - pending_delete_hosts_[old_site_instance_id] =
|
| - linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release());
|
| + if (old_render_frame_host->render_view_host()->IsRenderViewLive()) {
|
| + // If the old RFH is live, we are swapping it out and should keep track of
|
| + // it in case we navigate back to it, or it is waiting for the unload event
|
| + // to execute in the background.
|
| + // TODO(creis): Swap out the subframe in --site-per-process.
|
| + if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess))
|
| + DCHECK(old_render_frame_host->is_swapped_out() ||
|
| + !RenderViewHostImpl::IsRVHStateActive(
|
| + old_render_frame_host->render_view_host()->rvh_state()));
|
| + // Temp fix for http://crbug.com/90867 until we do a better cleanup to make
|
| + // sure we don't get different rvh instances for the same site instance
|
| + // in the same rvhmgr.
|
| + // TODO(creis): Clean this up.
|
| + RenderFrameHostMap::iterator iter =
|
| + swapped_out_hosts_.find(old_site_instance_id);
|
| + if (iter != swapped_out_hosts_.end() &&
|
| + iter->second != old_render_frame_host) {
|
| + // Delete the RFH that will be replaced in the map to avoid a leak.
|
| + delete iter->second;
|
| }
|
| - } else {
|
| + // If the RenderViewHost backing the RenderFrameHost is pending shutdown,
|
| + // the RenderFrameHost should be put in the map of RenderFrameHosts pending
|
| + // shutdown. Otherwise, it is stored in the map of swapped out
|
| + // RenderFrameHosts.
|
| + if (old_render_frame_host->render_view_host()->rvh_state() ==
|
| + RenderViewHostImpl::STATE_PENDING_SHUTDOWN) {
|
| + swapped_out_hosts_.erase(old_site_instance_id);
|
| + RFHPendingDeleteMap::iterator pending_delete_iter =
|
| + pending_delete_hosts_.find(old_site_instance_id);
|
| + if (pending_delete_iter == pending_delete_hosts_.end() ||
|
| + pending_delete_iter->second.get() != old_render_frame_host) {
|
| + pending_delete_hosts_[old_site_instance_id] =
|
| + linked_ptr<RenderFrameHostImpl>(old_render_frame_host);
|
| + }
|
| + } else {
|
| + swapped_out_hosts_[old_site_instance_id] = old_render_frame_host;
|
| + }
|
| +
|
| // If there are no active views in this SiteInstance, it means that
|
| // this RFH was the last active one in the SiteInstance. Now that we
|
| // know that all RFHs are swapped out, we can delete all the RFHs and RVHs
|
| @@ -1131,23 +1122,23 @@
|
| // swapped out list to simplify the deletion.
|
| if (!static_cast<SiteInstanceImpl*>(
|
| old_render_frame_host->GetSiteInstance())->active_view_count()) {
|
| - old_render_frame_host.reset();
|
| ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id);
|
| - } else {
|
| - proxy_hosts_[old_site_instance_id] = new RenderFrameProxyHost(
|
| - old_render_frame_host.Pass());
|
| + // This is deleted while cleaning up the SiteInstance's views.
|
| + old_render_frame_host = NULL;
|
| }
|
| + } else {
|
| + delete old_render_frame_host;
|
| }
|
| }
|
|
|
| void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance(
|
| int32 site_instance_id) {
|
| // First remove any swapped out RFH for this SiteInstance from our own list.
|
| - ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_);
|
| + ClearSwappedOutRFHsInSiteInstance(site_instance_id, frame_tree_node_);
|
|
|
| // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts
|
| // in the SiteInstance, then tell their respective FrameTrees to remove all
|
| - // RenderFrameProxyHosts corresponding to them.
|
| + // swapped out RenderFrameHosts corresponding to them.
|
| // TODO(creis): Replace this with a RenderFrameHostIterator that protects
|
| // against use-after-frees if a later element is deleted before getting to it.
|
| scoped_ptr<RenderWidgetHostIterator> widgets(
|
| @@ -1162,7 +1153,7 @@
|
| // |rvh| to Shutdown.
|
| FrameTree* tree = rvh->GetDelegate()->GetFrameTree();
|
| tree->ForEach(base::Bind(
|
| - &RenderFrameHostManager::ClearProxiesInSiteInstance,
|
| + &RenderFrameHostManager::ClearSwappedOutRFHsInSiteInstance,
|
| site_instance_id));
|
| }
|
| }
|
| @@ -1340,11 +1331,11 @@
|
| // We no longer need to prevent the process from exiting.
|
| pending_render_frame_host->GetProcess()->RemovePendingView();
|
|
|
| - // If the SiteInstance for the pending RFH is being used by others, don't
|
| - // delete the RFH, just swap it out and it can be reused at a later point.
|
| - SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>(
|
| - pending_render_frame_host->GetSiteInstance());
|
| - if (site_instance->active_view_count() > 1) {
|
| + // The pending RFH may already be on the swapped out list if we started to
|
| + // swap it back in and then canceled. If so, make sure it gets swapped out
|
| + // again. If it's not on the swapped out list (e.g., aborting a pending
|
| + // load), then it's safe to shut down.
|
| + if (IsOnSwappedOutList(pending_render_frame_host)) {
|
| // Any currently suspended navigations are no longer needed.
|
| pending_render_frame_host->render_view_host()->CancelSuspendedNavigations();
|
|
|
| @@ -1378,11 +1369,11 @@
|
| return;
|
|
|
| // We can't look it up by SiteInstance ID, which may no longer be valid.
|
| - for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
|
| - iter != proxy_hosts_.end();
|
| + for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin();
|
| + iter != swapped_out_hosts_.end();
|
| ++iter) {
|
| if (iter->second->render_view_host() == rvh) {
|
| - proxy_hosts_.erase(iter);
|
| + swapped_out_hosts_.erase(iter);
|
| break;
|
| }
|
| }
|
| @@ -1390,11 +1381,11 @@
|
|
|
| bool RenderFrameHostManager::IsRVHOnSwappedOutList(
|
| RenderViewHostImpl* rvh) const {
|
| - RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(
|
| + RenderFrameHostImpl* render_frame_host = GetSwappedOutRenderFrameHost(
|
| rvh->GetSiteInstance());
|
| - if (!proxy)
|
| + if (!render_frame_host)
|
| return false;
|
| - return IsOnSwappedOutList(proxy->render_frame_host());
|
| + return IsOnSwappedOutList(render_frame_host);
|
| }
|
|
|
| bool RenderFrameHostManager::IsOnSwappedOutList(
|
| @@ -1402,27 +1393,28 @@
|
| if (!rfh->GetSiteInstance())
|
| return false;
|
|
|
| - RenderFrameProxyHostMap::const_iterator iter = proxy_hosts_.find(
|
| + RenderFrameHostMap::const_iterator iter = swapped_out_hosts_.find(
|
| rfh->GetSiteInstance()->GetId());
|
| - if (iter == proxy_hosts_.end())
|
| + if (iter == swapped_out_hosts_.end())
|
| return false;
|
|
|
| - return iter->second->render_frame_host() == rfh;
|
| + return iter->second == rfh;
|
| }
|
|
|
| RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost(
|
| SiteInstance* instance) const {
|
| - RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
|
| - if (proxy)
|
| - return proxy->render_view_host();
|
| + RenderFrameHostImpl* render_frame_host =
|
| + GetSwappedOutRenderFrameHost(instance);
|
| + if (render_frame_host)
|
| + return render_frame_host->render_view_host();
|
| return NULL;
|
| }
|
|
|
| -RenderFrameProxyHost* RenderFrameHostManager::GetRenderFrameProxyHost(
|
| +RenderFrameHostImpl* RenderFrameHostManager::GetSwappedOutRenderFrameHost(
|
| SiteInstance* instance) const {
|
| - RenderFrameProxyHostMap::const_iterator iter =
|
| - proxy_hosts_.find(instance->GetId());
|
| - if (iter != proxy_hosts_.end())
|
| + RenderFrameHostMap::const_iterator iter =
|
| + swapped_out_hosts_.find(instance->GetId());
|
| + if (iter != swapped_out_hosts_.end())
|
| return iter->second;
|
|
|
| return NULL;
|
|
|