Skip to content

Commit

Permalink
Revitalize (and move) a block comment about how cross-process navigat…
Browse files Browse the repository at this point in the history
…ion works.

BUG=304341
TEST=comment-only CL

Review URL: https://codereview.chromium.org/648563002

Cr-Commit-Position: refs/heads/master@{#299337}
  • Loading branch information
nick-chromium authored and Commit bot committed Oct 13, 2014
1 parent cccacef commit bca18a0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 53 deletions.
49 changes: 47 additions & 2 deletions content/browser/frame_host/render_frame_host_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,53 @@ class RenderWidgetHostView;
class TestWebContents;
class WebUIImpl;

// Manages RenderFrameHosts for a FrameTreeNode. This class acts as a state
// machine to make cross-process navigations in a frame possible.
// Manages RenderFrameHosts for a FrameTreeNode. It maintains a
// current_frame_host() which is the content currently visible to the user. When
// a frame is told to navigate to a different web site (as determined by
// SiteInstance), it will replace its current RenderFrameHost with a new
// RenderFrameHost dedicated to the new SiteInstance, possibly in a new process.
//
// Cross-process navigation works like this:
//
// - RFHM::Navigate determines whether the destination is cross-site, and if so,
// it creates a pending_render_frame_host_.
//
// - The pending RFH is created in the "navigations suspended" state, meaning no
// navigation messages are sent to its renderer until the beforeunload handler
// has a chance to run in the current RFH.
//
// - The current RFH runs its beforeunload handler. If it returns false, we
// cancel all the pending logic. Otherwise we allow the pending RFH to send
// the navigation request to its renderer.
//
// - ResourceDispatcherHost receives a ResourceRequest on the IO thread for the
// main resource load from the pending RFH. It creates a
// CrossSiteResourceHandler to check whether a process transfer is needed when
// the request is ready to commit.
//
// - When RDH receives a response, the BufferedResourceHandler determines
// whether it is a navigation type that doesn't commit (e.g. download, 204 or
// error page). If so, it sends a message to the new renderer causing it to
// cancel the request, and the request (e.g. the download) proceeds. In this
// case, the pending RFH will never become the current RFH, but it remains
// until the next DidNavigate event for this WebContentsImpl.
//
// - After RDH receives a response and determines that it is safe and not a
// download, the CrossSiteResourceHandler checks whether a transfer for a
// redirect is needed. If so, it pauses the network response and starts an
// identical navigation in a new pending RFH. When the identical request is
// later received by RDH, the response is transferred and unpaused.
//
// - Otherwise, the network response commits in the pending RFH's renderer,
// which sends a DidCommitProvisionalLoad message back to the browser process.
//
// - RFHM::CommitPending makes visible the new RFH, and initiates the unload
// handler in the old RFH. The unload handler will complete in the background.
//
// - RenderFrameHostManager may keep the previous RFH alive as a
// RenderFrameProxyHost, to be used (for example) if the user goes back. The
// process only stays live if another tab is using it, but if so, the existing
// frame relationships will be maintained.
class CONTENT_EXPORT RenderFrameHostManager : public NotificationObserver {
public:
// Functions implemented by our owner that we need.
Expand Down
51 changes: 0 additions & 51 deletions content/browser/web_contents/web_contents_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,57 +115,6 @@
#include "base/mac/foundation_util.h"
#endif

// Cross-Site Navigations
//
// If a WebContentsImpl is told to navigate to a different web site (as
// determined by SiteInstance), it will replace its current RenderViewHost with
// a new RenderViewHost dedicated to the new SiteInstance. This works as
// follows:
//
// - RVHM::Navigate determines whether the destination is cross-site, and if so,
// it creates a pending_render_view_host_.
// - The pending RVH is "suspended," so that no navigation messages are sent to
// its renderer until the beforeunload JavaScript handler has a chance to
// run in the current RVH.
// - The pending RVH tells CrossSiteRequestManager (a thread-safe singleton)
// that it has a pending cross-site request. We will check this on the IO
// thread when deciding how to handle the response.
// - The current RVH runs its beforeunload handler. If it returns false, we
// cancel all the pending logic. Otherwise we allow the pending RVH to send
// the navigation request to its renderer.
// - ResourceDispatcherHost receives a ResourceRequest on the IO thread for the
// main resource load on the pending RVH. It creates a
// CrossSiteResourceHandler to check whether a process swap is needed when
// the request is ready to commit.
// - When RDH receives a response, the BufferedResourceHandler determines
// whether it is a download. If so, it sends a message to the new renderer
// causing it to cancel the request, and the download proceeds. For now, the
// pending RVH remains until the next DidNavigate event for this
// WebContentsImpl. This isn't ideal, but it doesn't affect any functionality.
// - After RDH receives a response and determines that it is safe and not a
// download, the CrossSiteResourceHandler checks whether a process swap is
// needed (either because CrossSiteRequestManager has state for it or because
// a transfer was needed for a redirect).
// - If so, CrossSiteResourceHandler pauses the response to first run the old
// page's unload handler. It does this by asynchronously calling the
// OnCrossSiteResponse method of RenderFrameHostManager on the UI thread,
// which sends a SwapOut message to the current RVH.
// - Once the unload handler is finished, RVHM::SwappedOut checks if a transfer
// to a new process is needed, based on the stored pending_nav_params_. (This
// is independent of whether we started out with a cross-process navigation.)
// - If not, it just tells the ResourceDispatcherHost to resume the response
// to its current RenderViewHost.
// - If so, it cancels the current pending RenderViewHost and sets up a new
// navigation using RequestTransferURL. When the transferred request
// arrives in the ResourceDispatcherHost, we transfer the response and
// resume it.
// - The pending renderer sends a FrameNavigate message that invokes the
// DidNavigate method. This replaces the current RVH with the
// pending RVH.
// - The previous renderer is kept swapped out in RenderFrameHostManager in case
// the user goes back. The process only stays live if another tab is using
// it, but if so, the existing frame relationships will be maintained.

namespace content {
namespace {

Expand Down

0 comments on commit bca18a0

Please sign in to comment.