Fix shutdown hang due to queued extension installs
Upon signing in to a profile (or login to Chrome OS) sync starts pulling down
extensions and installing them. This creates long tasks on the file thread.
If one of these tasks completes during browser shutdown, it initiates another
installation and more file I/O. This leads to Chrome's shutdown watchdog being
triggered, which on Chrome OS leads to a SIGABRT after 10 seconds.
This is one of our top-crashes on Chrome OS and can be easily triggered by
signing into an account (triggering sync of a bunch of apps) and immediately
signing out.
Fix it by preventing extension installation and updates after the browser has
started shutting down. We make a best-effort attempt to clean up, and on next
run the extension garbage collector cleans things up and sync continues.
BUG=155994
TEST=added to ExtensionServiceTest, existing browser_tests and unit_tests
Review URL: https://chromiumcodereview.appspot.com/11233015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163407 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 97198540..80fc68129 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -1497,6 +1497,23 @@
ExtensionErrorReporter::GetInstance()->ClearErrors();
}
+// Extensions don't install during shutdown.
+TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
+ InitializeEmptyExtensionService();
+
+ // Simulate shutdown.
+ service_->set_browser_terminating_for_test(true);
+
+ FilePath path = data_dir_.AppendASCII("good.crx");
+ scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
+ installer->set_allow_silent_install(true);
+ installer->InstallCrx(path);
+ loop_.RunAllPending();
+
+ EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
+ ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
+}
+
// This tests that the granted permissions preferences are correctly set when
// installing an extension.
TEST_F(ExtensionServiceTest, GrantedPermissions) {
@@ -2364,6 +2381,27 @@
version()->GetString());
}
+// Extensions should not be updated during browser shutdown.
+TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
+ InitializeEmptyExtensionService();
+
+ // Install an extension.
+ FilePath path = data_dir_.AppendASCII("good.crx");
+ const Extension* good = InstallCRX(path, INSTALL_NEW);
+ ASSERT_EQ(good_crx, good->id());
+
+ // Simulate shutdown.
+ service_->set_browser_terminating_for_test(true);
+
+ // Update should fail and extension should not be updated.
+ path = data_dir_.AppendASCII("good2.crx");
+ bool updated = service_->UpdateExtension(good_crx, path, GURL(), NULL);
+ ASSERT_FALSE(updated);
+ ASSERT_EQ("1.0.0.0",
+ service_->GetExtensionById(good_crx, false)->
+ version()->GetString());
+}
+
// Test updating a not-already-installed extension - this should fail
TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
InitializeEmptyExtensionService();