Bug 1702116 - Fix races in AddonManager & XPIDatabase r=kmag
authorBarret Rennie <barret@brennie.ca>
Thu, 22 Apr 2021 01:15:54 +0000
changeset 577041 02a698f7345f268ef2ec171c980fb7bcec3cbff5
parent 577040 314f85af022f974b0ef3c17e8932f16b021d761d
child 577042 885e78c7baa9447790edf8918722d2b15e8e334a
push id141707
push userbrennie@mozilla.com
push dateThu, 22 Apr 2021 01:18:18 +0000
treeherderautoland@02a698f7345f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1702116
milestone90.0a1
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 1702116 - Fix races in AddonManager & XPIDatabase r=kmag Differential Revision: https://phabricator.services.mozilla.com/D110363
browser/components/customizableui/CustomizeMode.jsm
toolkit/mozapps/extensions/AddonManager.jsm
toolkit/mozapps/extensions/internal/XPIDatabase.jsm
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -1626,18 +1626,18 @@ CustomizeMode.prototype = {
       themes.length = MAX_THEME_COUNT;
     }
 
     let footer = doc.getElementById("customization-lwtheme-menu-footer");
     let panel = footer.parentNode;
     for (let theme of themes) {
       let button = buildToolbarButton(theme);
       button.addEventListener("command", async () => {
+        onThemeSelected(panel);
         await button.theme.enable();
-        onThemeSelected(panel);
         AMTelemetry.recordActionEvent({
           object: "customize",
           action: "enable",
           extra: { type: "theme", addonId: theme.id },
         });
       });
       panel.insertBefore(button, footer);
     }
--- a/toolkit/mozapps/extensions/AddonManager.jsm
+++ b/toolkit/mozapps/extensions/AddonManager.jsm
@@ -3558,17 +3558,17 @@ var AddonManagerPrivate = {
     AddonManagerInternal.addStartupChange(aType, aID);
   },
 
   removeStartupChange(aType, aID) {
     AddonManagerInternal.removeStartupChange(aType, aID);
   },
 
   notifyAddonChanged(aID, aType, aPendingRestart) {
-    AddonManagerInternal.notifyAddonChanged(aID, aType, aPendingRestart);
+    return AddonManagerInternal.notifyAddonChanged(aID, aType, aPendingRestart);
   },
 
   updateAddonAppDisabledStates() {
     AddonManagerInternal.updateAddonAppDisabledStates();
   },
 
   updateAddonRepositoryData() {
     return AddonManagerInternal.updateAddonRepositoryData();
--- a/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
@@ -1966,29 +1966,35 @@ this.XPIDatabase = {
     Services.prefs.setCharPref(
       "extensions.activeThemeID",
       aId || DEFAULT_THEME_ID
     );
 
     let enableTheme;
 
     let addons = this.getAddonsByType("theme");
+    let updateDisabledStatePromises = [];
+
     for (let theme of addons) {
       if (theme.visible) {
         if (!aId && theme.id == DEFAULT_THEME_ID) {
           enableTheme = theme;
         } else if (theme.id != aId && !theme.pendingUninstall) {
-          this.updateAddonDisabledState(theme, {
-            userDisabled: true,
-            becauseSelecting: true,
-          });
+          updateDisabledStatePromises.push(
+            this.updateAddonDisabledState(theme, {
+              userDisabled: true,
+              becauseSelecting: true,
+            })
+          );
         }
       }
     }
 
+    await Promise.all(updateDisabledStatePromises);
+
     if (enableTheme) {
       await this.updateAddonDisabledState(enableTheme, {
         userDisabled: false,
         becauseSelecting: true,
       });
     }
   },
 
@@ -2632,20 +2638,19 @@ this.XPIDatabase = {
         await bootstrap.startup(BOOTSTRAP_REASONS.ADDON_ENABLE);
         AddonManagerPrivate.callAddonListeners("onEnabled", wrapper);
       }
     }
 
     // Notify any other providers that a new theme has been enabled
     if (aAddon.type === "theme") {
       if (!isDisabled) {
-        AddonManagerPrivate.notifyAddonChanged(aAddon.id, aAddon.type);
-        this.updateXPIStates(aAddon);
+        await AddonManagerPrivate.notifyAddonChanged(aAddon.id, aAddon.type);
       } else if (isDisabled && !becauseSelecting) {
-        AddonManagerPrivate.notifyAddonChanged(null, "theme");
+        await AddonManagerPrivate.notifyAddonChanged(null, "theme");
       }
     }
 
     return isDisabled;
   },
 
   /**
    * Update the appDisabled property for all add-ons.
@@ -2666,18 +2671,19 @@ this.XPIDatabase = {
     );
 
     await Promise.all(
       addons.map(addon =>
         AddonRepository.getCachedAddonByID(addon.id).then(aRepoAddon => {
           if (aRepoAddon) {
             logger.debug("updateAddonRepositoryData got info for " + addon.id);
             addon._repositoryAddon = aRepoAddon;
-            this.updateAddonDisabledState(addon);
+            return this.updateAddonDisabledState(addon);
           }
+          return undefined;
         })
       )
     );
   },
 
   /**
    * Adds the add-on's name and creator to the telemetry payload.
    *