chromium/chrome/browser/sessions/tab_loader.h

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SESSIONS_TAB_LOADER_H_
#define CHROME_BROWSER_SESSIONS_TAB_LOADER_H_

#include <utility>
#include <vector>

#include "base/containers/flat_set.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/resource_coordinator/tab_load_tracker.h"
#include "chrome/browser/sessions/session_restore_delegate.h"
#include "chrome/browser/sessions/tab_loader_delegate.h"

class TabLoaderTester;

// TabLoader is responsible for loading tabs after session restore has finished
// creating all the tabs. Tabs are loaded after a previously started tab
// finishes loading or a timeout is reached. If the timeout is reached before a
// tab finishes loading the timeout delay is doubled.
//
// TabLoader keeps a reference to itself when it's loading. When it has finished
// loading, it drops the reference. If another profile is restored while the
// TabLoader is loading, it will schedule its tabs to get loaded by the same
// TabLoader. When doing the scheduling, it holds a reference to the TabLoader.
// This is not part of SessionRestoreImpl so that synchronous destruction
// of SessionRestoreImpl doesn't have timing problems.
//
// TabLoader is effectively a state machine that guides session/tab restored
// tabs through being unloaded, to loading and finally to their loaded state. It
// does this while respecting memory pressure, a maximum simultaneous number of
// tabs loading in parallel, and a maximum tab load timeouts. At most one
// TabLoader exists at a moment; it owns itself and destroys itself once all
// tabs posted to it have been loaded.
//
// Beyond requesting tabs to load TabLoader maintains the following invariant:
//
// - If loads are ongoing and there are future tabs to load, then a timeout
//   timer is running.
//
// The general principle is that before returning control to the caller,
// the invariant is maintained. Extra care is taken in functions that may
// can cause reentrancy as they need to ensure the invariant is satisfied before
// passing control to the external code.
//
// Since the conditions for self-destroying can occur while deeply nested in our
// own code an entrance count is maintained to ensure it only happens on the way
// out of the outermost function.
class TabLoader : public base::RefCounted<TabLoader>,
                  public TabLoaderCallback,
                  public resource_coordinator::TabLoadTracker::Observer {};

#endif  // CHROME_BROWSER_SESSIONS_TAB_LOADER_H_