// 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_