This documents shutdown steps on Windows, Mac and Linux.
On Android, the system can terminate the Chrome app at any point without running any shutdown step.
TODO: Document ChromeOS shutdown.
Shutdown starts when nothing keeps Chrome alive. Typically, this happens when all browser windows are closed, but other things can keep Chrome alive.
When nothing keeps Chrome alive,
BrowserProcessImpl::Unpin asks the main thread's message loop to quit as soon as it no longer has tasks ready to run immediately.
base::RunLoop::QuitWhenIdle … BrowserProcessImpl::Unpin BrowserProcessImpl::OnKeepAliveStateChanged KeepAliveRegistry::OnKeepAliveStateChanged KeepAliveRegistry::Unregister ScopedKeepAlive::~ScopedKeepAlive ... Browser::UnregisterKeepAlive BrowserList::RemoveBrowser Browser::~Browser
Following this request,
ChromeBrowserMainParts::MainMessageLoopRun exits. Tasks posted to the main thread without a delay prior to this point are guaranteed to have run; tasks posted to the main thread after this point will never run.
BrowserMainRunnerImpl::Shutdown is called on the main thread. Within that method,
BrowserMainLoop::ShutdownThreadsAndCleanUp orchestrates the main shutdown steps.
ChromeBrowserMainParts::PostMainMessageLoopRun is invoked. It invokes the
PostMainMessageLoopRun method of each
ChromeBrowserMainExtraParts instance. This is a good place to perform shutdown steps of a component that require the IO thread, the
ThreadPool or the
Profile to still be available.
ChromeBrowserMainParts::PostMainMessageLoopRun also invokes
BrowserProcessImpl::StartTearDown which deletes many services owned by
g_browser_process). One of these services is the
ProfileManager. Deleting the
Profiles. As part of deleting a
KeyedServices are deleted, including:
The IO thread is joined. No IPC or Mojo can be received after this.
ThreadPool shutdown starts. At this point, no new
CONTINUE_ON_SHUTDOWN task can start running (they are deleted without running). The main thread blocks until all
SKIP_ON_SHUTDOWN tasks that started running prior to
ThreadPool shutdown start are complete, and all
BLOCK_SHUTDOWN tasks are complete (irrespective of whether they were posted before or after
ThreadPool shutdown start). When no more
SKIP_ON_SHUTDOWN is running and no more
BLOCK_SHUTDOWN task is queued or running, the main thread is unblocked and
ThreadPool shutdown is considered complete. Note:
CONTINUE_ON_SHUTDOWN tasks that started before
ThreadPool shutdown may still be running.
At this point, new tasks posted to the IO thread or to the
ThreadPool cannot run. It is illegal to post a
BLOCK_SHUTDOWN task to the
ThreadPool (enforced by a
ChromeBrowserMainParts::PostDestroyThreads is invoked. It invokes
BrowserProcessImpl::PostDestroyThreads. Since it is guaranteed that no
BLOCK_SHUTDOWN task is running at this point, it is a good place to delete objects accessed directly from these tasks.
Then, if a new Chrome executable, it is swapped with the current one (Windows-only).
upgrade_util::SwapNewChromeExeIfPresent browser_shutdown::ShutdownPostThreadsStop ChromeBrowserMainParts::PostDestroyThreads content::BrowserMainLoop::ShutdownThreadsAndCleanUp content::BrowserMainLoop::ShutdownThreadsAndCleanUp content::BrowserMainRunnerImpl::Shutdown