Bug 606076: XUL fastload is not cleared when new extensions are installed. r=bsmedberg, a=blocks-beta7
authorDave Townsend <dtownsend@oxymoronical.com>
Thu, 28 Oct 2010 12:21:04 -0700
changeset 56651 18db490056aad073a978b1079b0e852efa87f41e
parent 56650 16f18e41dcf349bed4dbfbaed141f784eed1fbda
child 56652 4aef2a4443e62f8a548a8e8d8673b72135ddef79
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, blocks-beta7
bugs606076
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 606076: XUL fastload is not cleared when new extensions are installed. r=bsmedberg, a=blocks-beta7
content/xul/document/src/nsXULPrototypeCache.cpp
toolkit/mozapps/extensions/test/xpcshell/test_bug594058.js
toolkit/mozapps/extensions/test/xpcshell/test_startup.js
--- a/content/xul/document/src/nsXULPrototypeCache.cpp
+++ b/content/xul/document/src/nsXULPrototypeCache.cpp
@@ -140,16 +140,17 @@ NS_NewXULPrototypeCache(nsISupports* aOu
     nsresult rv = result->QueryInterface(aIID, aResult);
 
     nsCOMPtr<nsIObserverService> obsSvc =
         mozilla::services::GetObserverService();
     if (obsSvc && NS_SUCCEEDED(rv)) {
         nsXULPrototypeCache *p = result;
         obsSvc->AddObserver(p, "chrome-flush-skin-caches", PR_FALSE);
         obsSvc->AddObserver(p, "chrome-flush-caches", PR_FALSE);
+        obsSvc->AddObserver(p, "startupcache-invalidate", PR_FALSE);
     }
 
     return rv;
 }
 
 /* static */ nsXULPrototypeCache*
 nsXULPrototypeCache::GetInstance()
 {
@@ -405,50 +406,59 @@ static PRBool gChecksumXULFastLoadFile =
 
 void
 nsXULPrototypeCache::AbortFastLoads()
 {
 #ifdef DEBUG_brendan
     NS_BREAK();
 #endif
 
-    // Save a strong ref to the FastLoad file, so we can remove it after we
-    // close open streams to it.
-    nsCOMPtr<nsIFile> file = gFastLoadFile;
-
     // Flush the XUL cache for good measure, in case we cached a bogus/downrev
     // script, somehow.
     Flush();
 
     // Clear the FastLoad set
     mFastLoadURITable.Clear();
 
-    if (! gFastLoadService)
-        return;
+    nsCOMPtr<nsIFastLoadService> fastLoadService = gFastLoadService;
+    nsCOMPtr<nsIFile> file = gFastLoadFile;
+
+    nsresult rv;
+
+    if (! fastLoadService) {
+        fastLoadService = do_GetFastLoadService();
+        if (! fastLoadService)
+            return;
+
+        rv = fastLoadService->NewFastLoadFile(XUL_FASTLOAD_FILE_BASENAME,
+                                              getter_AddRefs(file));
+        if (NS_FAILED(rv))
+            return;
+    }
 
     // Fetch the current input (if FastLoad file existed) or output (if we're
     // creating the FastLoad file during this app startup) stream.
     nsCOMPtr<nsIObjectInputStream> objectInput;
     nsCOMPtr<nsIObjectOutputStream> objectOutput;
-    gFastLoadService->GetInputStream(getter_AddRefs(objectInput));
-    gFastLoadService->GetOutputStream(getter_AddRefs(objectOutput));
+    fastLoadService->GetInputStream(getter_AddRefs(objectInput));
+    fastLoadService->GetOutputStream(getter_AddRefs(objectOutput));
 
     if (objectOutput) {
-        gFastLoadService->SetOutputStream(nsnull);
+        fastLoadService->SetOutputStream(nsnull);
 
         if (NS_SUCCEEDED(objectOutput->Close()) && gChecksumXULFastLoadFile)
-            gFastLoadService->CacheChecksum(gFastLoadFile,
-                                            objectOutput);
+            fastLoadService->CacheChecksum(file,
+                                           objectOutput);
     }
 
     if (objectInput) {
         // If this is the last of one or more XUL master documents loaded
         // together at app startup, close the FastLoad service's singleton
         // input stream now.
-        gFastLoadService->SetInputStream(nsnull);
+        fastLoadService->SetInputStream(nsnull);
         objectInput->Close();
     }
 
     // Now rename or remove the file.
     if (file) {
 #ifdef DEBUG
         // Remove any existing Aborted.mfasl files generated in previous runs.
         nsCOMPtr<nsIFile> existingAbortedFile;
@@ -457,23 +467,25 @@ nsXULPrototypeCache::AbortFastLoads()
             existingAbortedFile->SetLeafName(NS_LITERAL_STRING("Aborted.mfasl"));
             PRBool fileExists = PR_FALSE;
             existingAbortedFile->Exists(&fileExists);
             if (fileExists)
                 existingAbortedFile->Remove(PR_FALSE);
         }
         file->MoveToNative(nsnull, NS_LITERAL_CSTRING("Aborted.mfasl"));
 #else
-        file->Remove(PR_FALSE);
+        rv = file->Remove(PR_FALSE);
+        if (NS_FAILED(rv))
+            NS_WARNING("Failed to remove fastload file, fastload data may be outdated");
 #endif
     }
 
     // If the list is empty now, the FastLoad process is done.
-    NS_RELEASE(gFastLoadService);
-    NS_RELEASE(gFastLoadFile);
+    NS_IF_RELEASE(gFastLoadService);
+    NS_IF_RELEASE(gFastLoadFile);
 }
 
 
 void
 nsXULPrototypeCache::RemoveFromFastLoadSet(nsIURI* aURI)
 {
     mFastLoadURITable.Remove(aURI);
 }
--- a/toolkit/mozapps/extensions/test/xpcshell/test_bug594058.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug594058.js
@@ -7,56 +7,74 @@
 
 // Disables security checking our updates which haven't been signed
 Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
 
 const Ci = Components.interfaces;
 const extDir = gProfD.clone();
 extDir.append("extensions");
 
+var gFastLoadService = AM_Cc["@mozilla.org/fast-load-service;1"].
+                       getService(AM_Ci.nsIFastLoadService);
+var gFastLoadFile = null;
+
 /**
  * Start the test by installing extensions.
  */
 function run_test() {
   do_test_pending();
   let cachePurged = false;
 
   let obs = AM_Cc["@mozilla.org/observer-service;1"].
     getService(AM_Ci.nsIObserverService);
   obs.addObserver({
     observe: function(aSubject, aTopic, aData) {
       cachePurged = true;
     }
   }, "startupcache-invalidate", false);
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
+
+  gFastLoadFile = gFastLoadService.newFastLoadFile("XUL");
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
+
   startupManager();
+  // nsAppRunner takes care of clearing this when a new app is installed
+  do_check_true(gFastLoadFile.exists());
 
   installAllFiles([do_get_addon("test_bug594058")], function() {
     restartManager();
+    do_check_false(gFastLoadFile.exists());
+    gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
     do_check_true(cachePurged);
     cachePurged = false;
 
     // Now, make it look like we've updated the file. First, start the EM
     // so it records the bogus old time, then update the file and restart.
     let extFile = extDir.clone();
     let pastTime = extFile.lastModifiedTime - 5000;
     extFile.append("bug594058@tests.mozilla.org");
     setExtensionModifiedTime(extFile, pastTime);
     let otherFile = extFile.clone();
     otherFile.append("directory");
     otherFile.lastModifiedTime = pastTime;
     otherFile.append("file1");
     otherFile.lastModifiedTime = pastTime;
 
     restartManager();
+    do_check_false(gFastLoadFile.exists());
+    gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
     cachePurged = false;
 
     otherFile.lastModifiedTime = pastTime + 5000;
     restartManager();
+    do_check_false(gFastLoadFile.exists());
+    gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
     do_check_true(cachePurged);
     cachePurged = false;
 
     restartManager();
-    do_check_true(!cachePurged);
+    do_check_true(gFastLoadFile.exists());
+    do_check_false(cachePurged);
 
     do_test_finished();
   });  
 }
--- a/toolkit/mozapps/extensions/test/xpcshell/test_startup.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_startup.js
@@ -80,21 +80,29 @@ globalDir.append(gAppInfo.ID);
 registerDirectory("XRESysSExtPD", globalDir.parent);
 const userDir = gProfD.clone();
 userDir.append("extensions3");
 userDir.append(gAppInfo.ID);
 registerDirectory("XREUSysExt", userDir.parent);
 const profileDir = gProfD.clone();
 profileDir.append("extensions");
 
+var gFastLoadService = AM_Cc["@mozilla.org/fast-load-service;1"].
+                       getService(AM_Ci.nsIFastLoadService);
+var gFastLoadFile = null;
+
 // Set up the profile
 function run_test() {
   do_test_pending();
   startupManager();
 
+  gFastLoadFile = gFastLoadService.newFastLoadFile("XUL");
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
+
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
     do_check_eq(a1, null);
@@ -122,16 +130,19 @@ function run_test_1() {
   // the change in run_test_2 makes the last modified time change.
   setExtensionModifiedTime(dest, dest.lastModifiedTime - 5000);
 
   writeInstallRDFForExtension(addon3, profileDir);
   writeInstallRDFForExtension(addon4, profileDir);
   writeInstallRDFForExtension(addon5, profileDir);
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
+
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
     do_check_neq(a1, null);
@@ -198,16 +209,18 @@ function run_test_2() {
   writeInstallRDFForExtension(addon2, globalDir);
   addon2.version="2.3";
   writeInstallRDFForExtension(addon2, userDir);
   var dest = profileDir.clone();
   dest.append(do_get_expected_addon_name("addon3@tests.mozilla.org"));
   dest.remove(true);
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
@@ -252,16 +265,18 @@ function run_test_3() {
   dest.append(do_get_expected_addon_name("addon1@tests.mozilla.org"));
   dest.remove(true);
   dest = profileDir.clone();
   dest.append(do_get_expected_addon_name("addon2@tests.mozilla.org"));
   dest.remove(true);
   writeInstallRDFForExtension(addon3, profileDir, "addon4@tests.mozilla.org");
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
@@ -303,16 +318,18 @@ function run_test_3() {
   });
 }
 
 // Test that disabling an install location works
 function run_test_4() {
   Services.prefs.setIntPref("extensions.enabledScopes", AddonManager.SCOPE_SYSTEM);
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
@@ -335,16 +352,18 @@ function run_test_4() {
   });
 }
 
 // Switching disabled locations works
 function run_test_5() {
   Services.prefs.setIntPref("extensions.enabledScopes", AddonManager.SCOPE_USER);
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
@@ -373,16 +392,18 @@ function run_test_5() {
   });
 }
 
 // Resetting the pref makes everything visible again
 function run_test_6() {
   Services.prefs.clearUserPref("extensions.enabledScopes");
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
@@ -415,16 +436,18 @@ function run_test_6() {
 function run_test_7() {
   addon1.version = "1.2";
   writeInstallRDFForExtension(addon1, profileDir);
   var dest = userDir.clone();
   dest.append(do_get_expected_addon_name("addon2@tests.mozilla.org"));
   dest.remove(true);
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
@@ -462,16 +485,18 @@ function run_test_7() {
   });
 }
 
 // Disabling all locations still leaves the profile working
 function run_test_8() {
   Services.prefs.setIntPref("extensions.enabledScopes", 0);
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
@@ -503,16 +528,18 @@ function run_test_9() {
   dest.remove(true);
   dest = globalDir.clone();
   dest.append(do_get_expected_addon_name("addon2@tests.mozilla.org"));
   dest.remove(true);
   addon2.version = "2.4";
   writeInstallRDFForExtension(addon2, profileDir);
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
@@ -553,16 +580,18 @@ function run_test_9() {
 function run_test_10() {
   var dest = profileDir.clone();
   dest.append(do_get_expected_addon_name("addon1@tests.mozilla.org"));
   dest.remove(true);
   addon1.version = "1.3";
   writeInstallRDFForExtension(addon1, userDir);
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
@@ -603,16 +632,18 @@ function run_test_11() {
   var dest = userDir.clone();
   dest.append(do_get_expected_addon_name("addon1@tests.mozilla.org"));
   dest.remove(true);
   dest = profileDir.clone();
   dest.append(do_get_expected_addon_name("addon2@tests.mozilla.org"));
   dest.remove(true);
 
   restartManager();
+  do_check_false(gFastLoadFile.exists());
+  gFastLoadFile.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {