Backed out 6 changesets (bug 1553982) for breaking updates on Linux (bug 1680935) a=backout
authorCristina Coroiu <ccoroiu@mozilla.com>
Mon, 07 Dec 2020 11:35:41 +0200
changeset 559599 7167ab3f6e8d7b77439ac1cc7d9356bbaff02510
parent 559598 e090b0e10f5de9c444d145caeff7b166fbc17736
child 559677 7b5d474075c02870142b308fef983ee9d4da8ec7
push id38010
push userccoroiu@mozilla.com
push dateMon, 07 Dec 2020 09:37:31 +0000
treeherdermozilla-central@7167ab3f6e8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1553982, 1680935
milestone85.0a1
backs out78dce99516dd795169278abe112010517076570e
40d67c6dfdf30732bc110682870c50e8e5f1319d
71742fced1ba6515021cd9589adab610bd1e5257
9dcf78cd576f85862ea4f60dbdc782c09b61d11f
01d41760db294756674d450e9e3452303dec2ac0
5040354e75c212a3cfcb203614442df7858a18c0
first release with
nightly linux32
7167ab3f6e8d / 85.0a1 / 20201207093731 / files
nightly linux64
7167ab3f6e8d / 85.0a1 / 20201207093731 / files
nightly mac
7167ab3f6e8d / 85.0a1 / 20201207093731 / files
nightly win32
7167ab3f6e8d / 85.0a1 / 20201207093731 / files
nightly win64
7167ab3f6e8d / 85.0a1 / 20201207093731 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 6 changesets (bug 1553982) for breaking updates on Linux (bug 1680935) a=backout Backed out changeset 78dce99516dd (bug 1553982) Backed out changeset 40d67c6dfdf3 (bug 1553982) Backed out changeset 71742fced1ba (bug 1553982) Backed out changeset 9dcf78cd576f (bug 1553982) Backed out changeset 01d41760db29 (bug 1553982) Backed out changeset 5040354e75c2 (bug 1553982)
browser/components/customizableui/content/panelUI.inc.xhtml
browser/components/urlbar/tests/browser-tips/head.js
browser/locales/en-US/browser/appMenuNotifications.ftl
browser/modules/AppUpdater.jsm
browser/themes/shared/customizableui/panelUI.inc.css
browser/themes/shared/notification-icons.inc.css
browser/themes/shared/toolbarbutton-icons.inc.css
toolkit/components/build/components.conf
toolkit/components/telemetry/Histograms.json
toolkit/mozapps/update/UpdateListener.jsm
toolkit/mozapps/update/UpdateService.jsm
toolkit/mozapps/update/UpdateTelemetry.jsm
toolkit/mozapps/update/nsIUpdateService.idl
toolkit/mozapps/update/tests/browser/head.js
toolkit/mozapps/update/tests/data/semaphoreTestChildScript.js
toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
toolkit/mozapps/update/tests/moz.build
toolkit/mozapps/update/tests/unit_aus_update/updateSemaphore.js
toolkit/mozapps/update/tests/unit_aus_update/xpcshell.ini
toolkit/xre/GlobalSemaphore.cpp
toolkit/xre/GlobalSemaphore.h
toolkit/xre/moz.build
toolkit/xre/nsAppStartupNotifier.cpp
toolkit/xre/nsAppStartupNotifier.h
toolkit/xre/nsUpdateDriver.cpp
toolkit/xre/nsUpdateSyncManager.cpp
toolkit/xre/nsUpdateSyncManager.h
--- a/browser/components/customizableui/content/panelUI.inc.xhtml
+++ b/browser/components/customizableui/content/panelUI.inc.xhtml
@@ -149,30 +149,16 @@
                        checkboxhidden="true"
                        buttonhighlight="true"
                        hidden="true">
       <popupnotificationcontent id="update-restart-notification-content" orient="vertical">
         <description id="update-restart-description" data-lazy-l10n-id="appmenu-update-restart-message"></description>
       </popupnotificationcontent>
     </popupnotification>
 
-    <popupnotification id="appMenu-update-other-instance-notification"
-                       popupid="update-other-instance"
-                       data-lazy-l10n-id="appmenu-update-other-instance"
-                       data-l10n-attrs="buttonlabel, buttonaccesskey, secondarybuttonlabel, secondarybuttonaccesskey"
-                       closebuttonhidden="true"
-                       dropmarkerhidden="true"
-                       checkboxhidden="true"
-                       buttonhighlight="true"
-                       hidden="true">
-      <popupnotificationcontent id="update-other-instance-notification-content" orient="vertical">
-        <description id="update-other-instance-description" data-lazy-l10n-id="appmenu-update-other-instance-message"></description>
-      </popupnotificationcontent>
-    </popupnotification>
-
     <popupnotification id="appMenu-addon-installed-notification"
                        popupid="addon-installed"
                        closebuttonhidden="true"
                        secondarybuttonhidden="true"
                        data-lazy-l10n-id="appmenu-addon-private-browsing-installed"
                        data-l10n-attrs="buttonlabel, buttonaccesskey"
                        dropmarkerhidden="true"
                        checkboxhidden="true"
--- a/browser/components/urlbar/tests/browser-tips/head.js
+++ b/browser/components/urlbar/tests/browser-tips/head.js
@@ -51,87 +51,31 @@ add_task(async function init() {
   registerCleanupFunction(() => {
     // We need to reset the provider's appUpdater.status between tests so that
     // each test doesn't interfere with the next.
     UrlbarProviderInterventions.resetAppUpdater();
   });
 });
 
 /**
- * Override our binary path so that the update semaphore doesn't think more
- * than one instance of this test is running.
- * This is a heavily pared down copy of the function in xpcshellUtilsAUS.js.
- */
-function adjustGeneralPaths() {
-  let dirProvider = {
-    getFile(aProp, aPersistent) {
-      // Set the value of persistent to false so when this directory provider is
-      // unregistered it will revert back to the original provider.
-      aPersistent.value = false;
-      // The semaphore only needs XRE_EXECUTABLE_FILE, so that's all we need to
-      // override, we won't bother handling anything else.
-      if (aProp == XRE_EXECUTABLE_FILE) {
-        // The temp directory that the mochitest runner creates is unique per
-        // test, so its path can serve to provide the unique key that the
-        // update semaphore requires (it doesn't need for this to be the actual
-        // path to any real file, it's only used as an opaque string).
-        let tempPath = gEnv.get("MOZ_PROCESS_LOG");
-        let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
-        file.initWithPath(tempPath);
-        return file;
-      }
-      return null;
-    },
-    QueryInterface: ChromeUtils.generateQI(["nsIDirectoryServiceProvider"]),
-  };
-
-  let ds = Services.dirsvc.QueryInterface(Ci.nsIDirectoryService);
-  try {
-    ds.QueryInterface(Ci.nsIProperties).undefine(XRE_EXECUTABLE_FILE);
-  } catch (_ex) {
-    // We only override one property, so we have nothing to do if that fails.
-    return;
-  }
-  ds.registerProvider(dirProvider);
-  registerCleanupFunction(() => {
-    ds.unregisterProvider(dirProvider);
-    // Reset the update semaphore once again so that we know the semaphore we're
-    // interested in here will be closed properly (normally that happens during
-    // XPCOM shutdown, but that isn't consistent during tests).
-    let syncManager = Cc[
-      "@mozilla.org/updates/update-sync-manager;1"
-    ].getService(Ci.nsIUpdateSyncManager);
-    syncManager.resetSemaphore();
-  });
-
-  // Now that we've overridden the directory provider, the name of the update
-  // semaphore needs to be changed to match the overridden path.
-  let syncManager = Cc["@mozilla.org/updates/update-sync-manager;1"].getService(
-    Ci.nsIUpdateSyncManager
-  );
-  syncManager.resetSemaphore();
-}
-
-/**
  * Initializes a mock app update.  Adapted from runAboutDialogUpdateTest:
  * https://searchfox.org/mozilla-central/source/toolkit/mozapps/update/tests/browser/head.js
  *
  * @param {object} params
  *   See the files in toolkit/mozapps/update/tests/browser.
  */
 async function initUpdate(params) {
   gEnv.set("MOZ_TEST_SLOW_SKIP_UPDATE_STAGE", "1");
   await SpecialPowers.pushPrefEnv({
     set: [
       [PREF_APP_UPDATE_DISABLEDFORTESTING, false],
       [PREF_APP_UPDATE_URL_MANUAL, gDetailsURL],
     ],
   });
 
-  adjustGeneralPaths();
   await setupTestUpdater();
 
   let queryString = params.queryString ? params.queryString : "";
   let updateURL =
     URL_HTTP_UPDATE_SJS +
     "?detailsURL=" +
     gDetailsURL +
     queryString +
--- a/browser/locales/en-US/browser/appMenuNotifications.ftl
+++ b/browser/locales/en-US/browser/appMenuNotifications.ftl
@@ -27,24 +27,16 @@ appmenu-update-unsupported =
 appmenu-update-unsupported-message = The latest version of { -brand-shorter-name } is not supported on your system.
 appmenu-update-restart =
     .label = Restart to update { -brand-shorter-name }.
     .buttonlabel = Restart and Restore
     .buttonaccesskey = R
     .secondarybuttonlabel = Not Now
     .secondarybuttonaccesskey = N
 appmenu-update-restart-message = After a quick restart, { -brand-shorter-name } will restore all your open tabs and windows that are not in Private Browsing mode.
-appmenu-update-other-instance =
-    .label = { -brand-shorter-name } is unable to automatically update to the latest version.
-    .buttonlabel = Update { -brand-shorter-name } anyway
-    .buttonaccesskey = U
-    .secondarybuttonlabel = Not Now
-    .secondarybuttonaccesskey = N
-appmenu-update-other-instance-message = A new { -brand-shorter-name } update is available, but it can’t be installed because another copy of { -brand-shorter-name } is running. Close it to continue the update, or choose to update anyway (the other copy may not work correctly until you restart it).
-
 appmenu-addon-private-browsing-installed =
     .buttonlabel = Okay, Got It
     .buttonaccesskey = O
 appmenu-addon-post-install-message = Manage your add-ons by clicking <image data-l10n-name='addon-install-icon'></image> in the <image data-l10n-name='addon-menu-icon'></image> menu.
 appmenu-addon-post-install-incognito-checkbox =
     .label = Allow this extension to run in Private Windows
     .accesskey = A
 
--- a/browser/modules/AppUpdater.jsm
+++ b/browser/modules/AppUpdater.jsm
@@ -325,28 +325,17 @@ class AppUpdater {
         // downloading so return early and do NOT remove the download listener!
         break;
       case Cr.NS_BINDING_ABORTED:
         // Do not remove UI listener since the user may resume downloading again.
         break;
       case Cr.NS_OK:
         this.aus.removeDownloadListener(this);
         if (this.updateStagingEnabled) {
-          // It could be that another instance was started during the download,
-          // and if that happened, then we actually should not advance to the
-          // STAGING status because the staging process isn't really happening
-          // until that instance exits (or we time out waiting).
-          if (this.aus.isOtherInstanceHandlingUpdates) {
-            this._setStatus(AppUpdater.OTHER_INSTANCE_HANDLING_UPDATES);
-          } else {
-            this._setStatus(AppUpdater.STATUS.STAGING);
-          }
-          // But we should register the staging observer in either case, because
-          // if we do time out waiting for the other instance to exit, then
-          // staging really will start at that point.
+          this._setStatus(AppUpdater.STATUS.STAGING);
           this._awaitStagingComplete();
         } else {
           this._awaitDownloadComplete();
         }
         break;
       default:
         this.aus.removeDownloadListener(this);
         this._setStatus(AppUpdater.STATUS.DOWNLOAD_FAILED);
--- a/browser/themes/shared/customizableui/panelUI.inc.css
+++ b/browser/themes/shared/customizableui/panelUI.inc.css
@@ -64,44 +64,41 @@
 #PanelUI-menu-button[badge-status="extension-new-tab"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
 #PanelUI-menu-button[badge-status="download-success"] > .toolbarbutton-badge-stack > .toolbarbutton-badge {
   display: none;
 }
 
 #PanelUI-menu-button[badge-status="update-available"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
 #PanelUI-menu-button[badge-status="update-downloading"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
 #PanelUI-menu-button[badge-status="update-manual"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
-#PanelUI-menu-button[badge-status="update-other-instance"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
 #PanelUI-menu-button[badge-status="update-restart"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
 #PanelUI-menu-button[badge-status="update-unsupported"] > .toolbarbutton-badge-stack > .toolbarbutton-badge {
   border-radius: 50%;
   box-shadow: none;
   /* "!important" is necessary to override the rule in toolbarbutton.css */
   margin: -7px 0 0 !important;
   margin-inline-end: -4px !important;
   min-width: 12px;
   min-height: 12px;
 }
 
 #PanelUI-menu-button[badge-status="update-available"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
 #PanelUI-menu-button[badge-status="update-downloading"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
 #PanelUI-menu-button[badge-status="update-manual"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
-#PanelUI-menu-button[badge-status="update-other-instance"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
 #PanelUI-menu-button[badge-status="update-restart"] > .toolbarbutton-badge-stack > .toolbarbutton-badge {
   background: #74BF43 url(chrome://browser/skin/update-badge.svg) no-repeat center;
 }
 
 #PanelUI-menu-button[badge-status="update-unsupported"] > .toolbarbutton-badge-stack > .toolbarbutton-badge {
   background: #FFE900 url(chrome://browser/skin/update-badge.svg) no-repeat center;
 }
 
 .panel-banner-item[notificationid="update-available"]::after,
 .panel-banner-item[notificationid="update-downloading"]::after,
 .panel-banner-item[notificationid="update-manual"]::after,
-.panel-banner-item[notificationid="update-other-instance"]::after,
 .panel-banner-item[notificationid="update-restart"]::after {
   background: #74BF43 url(chrome://browser/skin/update-badge.svg) no-repeat center;
   border-radius: 50%;
 }
 
 .panel-banner-item[notificationid="update-unsupported"]::after {
   background: #FFE900 url(chrome://browser/skin/update-badge.svg) no-repeat center;
   border-radius: 50%;
--- a/browser/themes/shared/notification-icons.inc.css
+++ b/browser/themes/shared/notification-icons.inc.css
@@ -410,17 +410,16 @@ html|*#webRTC-previewVideo {
   }
 }
 %endif
 
 /* UPDATE */
 .popup-notification-icon[popupid="update-available"],
 .popup-notification-icon[popupid="update-downloading"],
 .popup-notification-icon[popupid="update-manual"],
-.popup-notification-icon[popupid="update-other-instance"],
 .popup-notification-icon[popupid="update-restart"] {
   background: #74BF43 url(chrome://browser/skin/notification-icons/update.svg) no-repeat center;
   border-radius: 50%;
 }
 
 .popup-notification-icon[popupid="update-unsupported"] {
   background: #FFE900 url(chrome://browser/skin/notification-icons/update.svg) no-repeat center;
   border-radius: 50%;
--- a/browser/themes/shared/toolbarbutton-icons.inc.css
+++ b/browser/themes/shared/toolbarbutton-icons.inc.css
@@ -297,17 +297,16 @@ toolbar[brighttext] {
 
 #PanelUI-menu-button {
   list-style-image: url("chrome://browser/skin/menu.svg");
 }
 
 #PanelUI-menu-button[badge-status="update-available"],
 #PanelUI-menu-button[badge-status="update-downloading"],
 #PanelUI-menu-button[badge-status="update-manual"],
-#PanelUI-menu-button[badge-status="update-other-instance"],
 #PanelUI-menu-button[badge-status="update-restart"] {
   list-style-image: url("chrome://browser/skin/menu-badged.svg");
 }
 
 #cut-button {
   list-style-image: url("chrome://browser/skin/edit-cut.svg");
 }
 
--- a/toolkit/components/build/components.conf
+++ b/toolkit/components/build/components.conf
@@ -164,26 +164,16 @@ Classes = [
 if defined('MOZ_UPDATER') and not IS_ANDROID:
     Classes += [
         {
             'cid': '{f3dcf644-79e8-4f59-a1bb-878454488ef9}',
             'contract_ids': ['@mozilla.org/updates/update-processor;1'],
             'type': 'nsUpdateProcessor',
             'headers': ['/toolkit/xre/nsUpdateDriver.h'],
         },
-        {
-            'cid': '{cf4c4487-66d9-4e18-a2e9-39002245332f}',
-            'contract_ids': ['@mozilla.org/updates/update-sync-manager;1'],
-            'type': 'nsUpdateSyncManager',
-            'singleton': True,
-            'headers': ['/toolkit/xre/nsUpdateSyncManager.h'],
-            'constructor': 'nsUpdateSyncManager::GetSingleton',
-            'processes': ProcessSelector.MAIN_PROCESS_ONLY,
-            'categories': {'xpcom-startup': 'nsUpdateSyncManager'},
-        },
     ]
 
 if not defined('MOZ_DISABLE_PARENTAL_CONTROLS'):
     Classes += [
         {
             'cid': '{580530e5-118c-4bc7-ab88-bc2cd2b97223}',
             'contract_ids': ['@mozilla.org/parental-controls-service;1'],
             'type': 'nsParentalControlsService',
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -6773,64 +6773,64 @@
     "description": "Update: the update wizard page displayed when the UI was closed (mapped in toolkit/mozapps/update/UpdateTelemetry.jsm)"
   },
   "UPDATE_NOTIFICATION_SHOWN": {
     "record_in_processes": ["main"],
     "products": ["firefox", "fennec"],
     "alert_emails": ["application-update-telemetry-alerts@mozilla.com", "bytesized@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
-    "bug_numbers": [893505, 1521427, 1553982],
+    "bug_numbers": [893505, 1521427],
     "releaseChannelCollection": "opt-out",
     "description": "Update: the application update doorhanger type that was displayed.",
-    "labels": ["restart", "available", "manual", "unsupported", "otherinstance"]
+    "labels": ["restart", "available", "manual", "unsupported"]
   },
   "UPDATE_NOTIFICATION_BADGE_SHOWN": {
     "record_in_processes": ["main"],
     "products": ["firefox", "fennec"],
     "alert_emails": ["application-update-telemetry-alerts@mozilla.com", "bytesized@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
-    "bug_numbers": [893505, 1365204, 1521427, 1553982],
+    "bug_numbers": [893505, 1365204, 1521427],
     "releaseChannelCollection": "opt-out",
     "description": "Update: the application update badge type that was displayed.",
-    "labels": ["restart", "available", "manual", "unsupported", "otherinstance"]
+    "labels": ["restart", "available", "manual", "unsupported"]
   },
   "UPDATE_NOTIFICATION_DISMISSED": {
     "record_in_processes": ["main"],
     "products": ["firefox", "fennec"],
     "alert_emails": ["application-update-telemetry-alerts@mozilla.com", "bytesized@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
-    "bug_numbers": [893505, 1521427, 1553982],
+    "bug_numbers": [893505, 1521427],
     "releaseChannelCollection": "opt-out",
     "description": "Update: the dismiss action was executed for this application update doorhanger type.",
-    "labels": ["restart", "available", "manual", "unsupported", "otherinstance"]
+    "labels": ["restart", "available", "manual", "unsupported"]
   },
   "UPDATE_NOTIFICATION_MAIN_ACTION_DOORHANGER": {
     "record_in_processes": ["main"],
     "products": ["firefox", "fennec"],
     "alert_emails": ["application-update-telemetry-alerts@mozilla.com", "bytesized@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
-    "bug_numbers": [893505, 1521427, 1553982],
+    "bug_numbers": [893505, 1521427],
     "releaseChannelCollection": "opt-out",
     "description": "Update: the main update action was initiated for this application update doorhanger type.",
-    "labels": ["restart", "available", "manual", "unsupported", "otherinstance"]
+    "labels": ["restart", "available", "manual", "unsupported"]
   },
   "UPDATE_NOTIFICATION_MAIN_ACTION_MENU": {
     "record_in_processes": ["main"],
     "products": ["firefox", "fennec"],
     "alert_emails": ["application-update-telemetry-alerts@mozilla.com", "bytesized@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
-    "bug_numbers": [893505, 1521427, 1553982],
+    "bug_numbers": [893505, 1521427],
     "releaseChannelCollection": "opt-out",
     "description": "Update: the update action was initiated from the PanelUI application update menu item.",
-    "labels": ["restart", "available", "manual", "unsupported", "otherinstance"]
+    "labels": ["restart", "available", "manual", "unsupported"]
   },
   "UPDATE_CAN_USE_BITS_EXTERNAL": {
     "record_in_processes": ["main"],
     "products": ["firefox", "fennec"],
     "alert_emails": ["application-update-telemetry-alerts@mozilla.com", "bytesized@mozilla.com"],
     "expires_in_version": "never",
     "kind": "categorical",
     "labels": [
--- a/toolkit/mozapps/update/UpdateListener.jsm
+++ b/toolkit/mozapps/update/UpdateListener.jsm
@@ -5,46 +5,36 @@
 "use strict";
 
 var EXPORTED_SYMBOLS = ["UpdateListener"];
 
 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const { clearTimeout, setTimeout } = ChromeUtils.import(
   "resource://gre/modules/Timer.jsm"
 );
-const { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
 
 ChromeUtils.defineModuleGetter(
   this,
   "AppMenuNotifications",
   "resource://gre/modules/AppMenuNotifications.jsm"
 );
 
-XPCOMUtils.defineLazyServiceGetter(
-  this,
-  "AppUpdateService",
-  "@mozilla.org/updates/update-service;1",
-  "nsIApplicationUpdateService"
-);
-
 const PREF_APP_UPDATE_UNSUPPORTED_URL = "app.update.unsupported.url";
 
 // Setup the hamburger button badges for updates.
 var UpdateListener = {
   timeouts: [],
 
   get badgeWaitTime() {
     return Services.prefs.getIntPref("app.update.badgeWaitTime", 4 * 24 * 3600); // 4 days
   },
 
   init() {
     // Persist the unsupported notification across sessions. If at some point an
-    // update is found this pref is cleared and the notification won't be shown.
+    // update is found this pref is cleared and the notifcation won't be shown.
     let url = Services.prefs.getCharPref(PREF_APP_UPDATE_UNSUPPORTED_URL, null);
     if (url) {
       this.showUpdateNotification("unsupported", true, true, win =>
         this.openUnsupportedUpdateUrl(win, url)
       );
     }
   },
 
@@ -121,19 +111,17 @@ var UpdateListener = {
     mainActionDismiss,
     dismissed,
     mainAction,
     beforeShowDoorhanger
   ) {
     const addTelemetry = id => {
       // No telemetry for the "downloading" state.
       if (type !== "downloading") {
-        // Histogram category labels can't have dashes in them.
-        let telemetryType = type.replaceAll("-", "");
-        Services.telemetry.getHistogramById(id).add(telemetryType);
+        Services.telemetry.getHistogramById(id).add(type);
       }
     };
     let action = {
       callback(win, fromDoorhanger) {
         if (fromDoorhanger) {
           addTelemetry("UPDATE_NOTIFICATION_MAIN_ACTION_DOORHANGER");
         } else {
           addTelemetry("UPDATE_NOTIFICATION_MAIN_ACTION_MENU");
@@ -157,32 +145,32 @@ var UpdateListener = {
     );
     if (dismissed) {
       addTelemetry("UPDATE_NOTIFICATION_BADGE_SHOWN");
     } else {
       addTelemetry("UPDATE_NOTIFICATION_SHOWN");
     }
   },
 
-  showRestartNotification(update, dismissed) {
-    let notification = AppUpdateService.isOtherInstanceHandlingUpdates
-      ? "other-instance"
-      : "restart";
-    this.showUpdateNotification(notification, true, dismissed, () =>
+  showRestartNotification(dismissed) {
+    this.showUpdateNotification("restart", true, dismissed, () =>
       this.requestRestart()
     );
   },
 
   showUpdateAvailableNotification(update, dismissed) {
     this.showUpdateNotification(
       "available",
       false,
       dismissed,
       () => {
-        AppUpdateService.downloadUpdate(update, true);
+        let updateService = Cc[
+          "@mozilla.org/updates/update-service;1"
+        ].getService(Ci.nsIApplicationUpdateService);
+        updateService.downloadUpdate(update, true);
       },
       doc => this.replaceReleaseNotes(doc, update, "updateAvailableWhatsNew")
     );
   },
 
   showManualUpdateNotification(update, dismissed) {
     this.showUpdateNotification(
       "manual",
@@ -260,32 +248,29 @@ var UpdateListener = {
       case "success":
         this.clearCallbacks();
 
         let badgeWaitTimeMs = this.badgeWaitTime * 1000;
         let doorhangerWaitTimeMs = update.promptWaitTime * 1000;
 
         if (badgeWaitTimeMs < doorhangerWaitTimeMs) {
           this.addTimeout(badgeWaitTimeMs, () => {
-            // Skip the badge if we're waiting for another instance.
-            if (!AppUpdateService.isOtherInstanceHandlingUpdates) {
-              this.showRestartNotification(update, true);
-            }
+            this.showRestartNotification(true);
 
             // doorhangerWaitTimeMs is relative to when we initially received
             // the event. Since we've already waited badgeWaitTimeMs, subtract
             // that from doorhangerWaitTimeMs.
             let remainingTime = doorhangerWaitTimeMs - badgeWaitTimeMs;
             this.addTimeout(remainingTime, () => {
-              this.showRestartNotification(update, false);
+              this.showRestartNotification(false);
             });
           });
         } else {
           this.addTimeout(doorhangerWaitTimeMs, () => {
-            this.showRestartNotification(update, false);
+            this.showRestartNotification(false);
           });
         }
         break;
     }
   },
 
   handleUpdateAvailable(update, status) {
     switch (status) {
--- a/toolkit/mozapps/update/UpdateService.jsm
+++ b/toolkit/mozapps/update/UpdateService.jsm
@@ -47,22 +47,16 @@ const UPDATESERVICE_CID = Components.ID(
 
 const PREF_APP_UPDATE_ALTUPDATEDIRPATH = "app.update.altUpdateDirPath";
 const PREF_APP_UPDATE_BACKGROUNDERRORS = "app.update.backgroundErrors";
 const PREF_APP_UPDATE_BACKGROUNDMAXERRORS = "app.update.backgroundMaxErrors";
 const PREF_APP_UPDATE_BITS_ENABLED = "app.update.BITS.enabled";
 const PREF_APP_UPDATE_CANCELATIONS = "app.update.cancelations";
 const PREF_APP_UPDATE_CANCELATIONS_OSX = "app.update.cancelations.osx";
 const PREF_APP_UPDATE_CANCELATIONS_OSX_MAX = "app.update.cancelations.osx.max";
-const PREF_APP_UPDATE_CHECK_ONLY_INSTANCE_ENABLED =
-  "app.update.checkOnlyInstance.enabled";
-const PREF_APP_UPDATE_CHECK_ONLY_INSTANCE_INTERVAL =
-  "app.update.checkOnlyInstance.interval";
-const PREF_APP_UPDATE_CHECK_ONLY_INSTANCE_TIMEOUT =
-  "app.update.checkOnlyInstance.timeout";
 const PREF_APP_UPDATE_DISABLEDFORTESTING = "app.update.disabledForTesting";
 const PREF_APP_UPDATE_DOWNLOAD_ATTEMPTS = "app.update.download.attempts";
 const PREF_APP_UPDATE_DOWNLOAD_MAXATTEMPTS = "app.update.download.maxAttempts";
 const PREF_APP_UPDATE_ELEVATE_NEVER = "app.update.elevate.never";
 const PREF_APP_UPDATE_ELEVATE_VERSION = "app.update.elevate.version";
 const PREF_APP_UPDATE_ELEVATE_ATTEMPTS = "app.update.elevate.attempts";
 const PREF_APP_UPDATE_ELEVATE_MAXATTEMPTS = "app.update.elevate.maxAttempts";
 const PREF_APP_UPDATE_LANGPACK_ENABLED = "app.update.langpack.enabled";
@@ -246,28 +240,16 @@ const APPID_TO_TOPIC = {
 
 // The interval for the update xml write deferred task.
 const XML_SAVER_INTERVAL_MS = 200;
 
 // How long after a patch has downloaded should we wait for language packs to
 // update before proceeding anyway.
 const LANGPACK_UPDATE_DEFAULT_TIMEOUT = 300000;
 
-// Interval between rechecks for other instances after the initial check finds
-// at least one other instance.
-const ONLY_INSTANCE_CHECK_DEFAULT_POLL_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
-
-// Wait this long after detecting that another instance is running (having been
-// polling that entire time) before giving up and applying the update anyway.
-const ONLY_INSTANCE_CHECK_DEFAULT_TIMEOUT_MS = 6 * 60 * 60 * 1000; // 6 hours
-
-// The other instance check timeout can be overridden via a pref, but we limit
-// that value to this so that the pref can't effectively disable the feature.
-const ONLY_INSTANCE_CHECK_MAX_TIMEOUT_MS = 2 * 24 * 60 * 60 * 1000; // 2 days
-
 // Object to keep track of the current phase of the update and whether there
 // has been a write failure for the phase so only one telemetry ping is made
 // for the phase.
 var gUpdateFileWriteInfo = { phase: null, failure: false };
 var gUpdateMutexHandle = null;
 // The permissions of the update directory should be fixed no more than once per
 // session
 var gUpdateDirPermissionFixAttempted = false;
@@ -330,116 +312,16 @@ function unwrap(obj) {
  *
  * When the language packs finish staging the nsIUpdate entriy is removed from
  * this map so if the entry is still there then language pack updates are in
  * progress.
  */
 const LangPackUpdates = new WeakMap();
 
 /**
- * When we're polling to see if other running instances of the application have
- * exited, there's no need to ever start polling again in parallel. To prevent
- * doing that, we keep track of the promise that resolves when polling completes
- * and return that if a second simultaneous poll is requested, so that the
- * multiple callers end up waiting for the same promise to resolve.
- */
-let gOtherInstancePollPromise;
-
-/**
- * Query the update sync manager to see if another instance of this same
- * installation of this application is currently running, under the context of
- * any operating system user (not just the current one).
- * This function immediately returns the current, instantaneous status of any
- * other instances.
- *
- * @return true if at least one other instance is running, false if not
- */
-function isOtherInstanceRunning(callback) {
-  const checkEnabled = Services.prefs.getBoolPref(
-    PREF_APP_UPDATE_CHECK_ONLY_INSTANCE_ENABLED,
-    true
-  );
-  if (!checkEnabled) {
-    LOG("isOtherInstanceRunning - disabled by pref, skipping check");
-    return false;
-  }
-
-  let syncManager = Cc["@mozilla.org/updates/update-sync-manager;1"].getService(
-    Ci.nsIUpdateSyncManager
-  );
-  return syncManager.isOtherInstanceRunning();
-}
-
-/**
- * Query the update sync manager to see if another instance of this same
- * installation of this application is currently running, under the context of
- * any operating system user (not just the one running this instance).
- * This function polls for the status of other instances continually
- * (asynchronously) until either none exist or a timeout expires.
- *
- * @return a Promise that resolves with false if at any point during polling no
- *         other instances can be found, or resolves with true if the timeout
- *         expires when other instances are still running
- */
-function waitForOtherInstances() {
-  // If we're already in the middle of a poll, reuse it rather than start again.
-  if (gOtherInstancePollPromise) {
-    return gOtherInstancePollPromise;
-  }
-
-  let timeout = Services.prefs.getIntPref(
-    PREF_APP_UPDATE_CHECK_ONLY_INSTANCE_TIMEOUT,
-    ONLY_INSTANCE_CHECK_DEFAULT_TIMEOUT_MS
-  );
-  // Don't allow the pref to set a super high timeout and break this feature.
-  if (timeout > ONLY_INSTANCE_CHECK_MAX_TIMEOUT_MS) {
-    timeout = ONLY_INSTANCE_CHECK_MAX_TIMEOUT_MS;
-  }
-
-  let interval = Services.prefs.getIntPref(
-    PREF_APP_UPDATE_CHECK_ONLY_INSTANCE_INTERVAL,
-    ONLY_INSTANCE_CHECK_DEFAULT_POLL_INTERVAL_MS
-  );
-  // Don't allow an interval longer than the timeout.
-  interval = Math.min(interval, timeout);
-
-  let iterations = 0;
-  const maxIterations = Math.ceil(timeout / interval);
-
-  gOtherInstancePollPromise = new Promise(function(resolve, reject) {
-    let poll = function() {
-      iterations++;
-      if (!isOtherInstanceRunning()) {
-        LOG("waitForOtherInstances - no other instances found, exiting");
-        resolve(false);
-        gOtherInstancePollPromise = undefined;
-      } else if (iterations >= maxIterations) {
-        LOG(
-          "waitForOtherInstances - timeout expired while other instances " +
-            "are still running"
-        );
-        resolve(true);
-        gOtherInstancePollPromise = undefined;
-      } else if (iterations + 1 == maxIterations && timeout % interval != 0) {
-        // In case timeout isn't a multiple of interval, set the next timeout
-        // for the remainder of the time rather than for the usual interval.
-        setTimeout(poll, timeout % interval);
-      } else {
-        setTimeout(poll, interval);
-      }
-    };
-
-    LOG("waitForOtherInstances - beginning polling");
-    poll();
-  });
-
-  return gOtherInstancePollPromise;
-}
-
-/**
  * Tests to make sure that we can write to a given directory.
  *
  * @param updateTestFile a test file in the directory that needs to be tested.
  * @param createDirectory whether a test directory should be created.
  * @throws if we don't have right access to the directory.
  */
 function testWriteAccess(updateTestFile, createDirectory) {
   const NORMAL_FILE_TYPE = Ci.nsIFile.NORMAL_FILE_TYPE;
@@ -2459,17 +2341,17 @@ UpdateService.prototype = {
         ? cleanupDownloadingUpdate
         : cleanupReadyUpdate;
 
     if (!this.canApplyUpdates) {
       LOG(
         "UpdateService:_postUpdateProcessing - unable to apply " +
           "updates... returning early"
       );
-      if (hasUpdateMutex()) {
+      if (!this.isOtherInstanceHandlingUpdates) {
         // If the update is present in the update directory somehow,
         // it would prevent us from notifying the user of further updates.
         cleanupUpdate();
       }
       return;
     }
 
     var um = Cc["@mozilla.org/updates/update-manager;1"].getService(
@@ -3007,18 +2889,16 @@ UpdateService.prototype = {
           );
         } else if (this.disabledByPolicy) {
           AUSTLMY.pingCheckCode(
             this._pingSuffix,
             AUSTLMY.CHK_DISABLED_BY_POLICY
           );
         } else if (!hasUpdateMutex()) {
           AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_NO_MUTEX);
-        } else if (isOtherInstanceRunning()) {
-          AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_OTHER_INSTANCE);
         } else if (!this.canCheckForUpdates) {
           AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_UNABLE_TO_CHECK);
         }
 
         this.backgroundChecker.checkForUpdates(this, false);
       });
   },
 
@@ -3334,57 +3214,46 @@ UpdateService.prototype = {
     if (!hasUpdateMutex()) {
       LOG(
         "UpdateService.canCheckForUpdates - unable to check for updates, " +
           "unable to acquire update mutex"
       );
       return false;
     }
 
-    if (isOtherInstanceRunning()) {
-      // This doesn't block update checks, but we will have to wait until either
-      // the other instance is gone or we time out waiting for it.
-      LOG(
-        "UpdateService.canCheckForUpdates - another instance is holding the " +
-          "semaphore, will need to wait for it prior to checking for updates"
-      );
-    }
-
     LOG("UpdateService.canCheckForUpdates - able to check for updates");
     return true;
   },
 
   /**
    * See nsIUpdateService.idl
    */
   get elevationRequired() {
     return getElevationRequired();
   },
 
   /**
    * See nsIUpdateService.idl
    */
   get canApplyUpdates() {
-    return (
-      getCanApplyUpdates() && hasUpdateMutex() && !isOtherInstanceRunning()
-    );
+    return getCanApplyUpdates() && hasUpdateMutex();
   },
 
   /**
    * See nsIUpdateService.idl
    */
   get canStageUpdates() {
     return getCanStageUpdates();
   },
 
   /**
    * See nsIUpdateService.idl
    */
   get isOtherInstanceHandlingUpdates() {
-    return !hasUpdateMutex() || isOtherInstanceRunning();
+    return !hasUpdateMutex();
   },
 
   /**
    * A set of download listeners to be notified by this._downloader when it
    * receives nsIRequestObserver or nsIProgressEventSink method calls.
    *
    * These are stored on the UpdateService rather than on the Downloader,
    * because they ought to persist across multiple Downloader instances.
@@ -3546,17 +3415,17 @@ UpdateService.prototype = {
     }
     LOG("Logging current UpdateService status:");
     // These getters print their own logging
     this.canCheckForUpdates;
     this.canApplyUpdates;
     this.canStageUpdates;
     LOG("Elevation required: " + this.elevationRequired);
     LOG(
-      "Other instance of the application currently running: " +
+      "Update being handled by other instance: " +
         this.isOtherInstanceHandlingUpdates
     );
     LOG("Downloading: " + !!this.isDownloading);
     if (this._downloader && this._downloader.isBusy) {
       LOG("Downloading complete update: " + this._downloader.isCompleteUpdate);
       LOG("Downloader using BITS: " + this._downloader.usingBits);
       if (this._downloader._patch) {
         // This will print its own logging
@@ -3989,17 +3858,17 @@ UpdateManager.prototype = {
       );
     }
     return Promise.all(promises);
   },
 
   /**
    * See nsIUpdateService.idl
    */
-  refreshUpdateStatus: async function UM_refreshUpdateStatus() {
+  refreshUpdateStatus: function UM_refreshUpdateStatus() {
     var update = this._readyUpdate;
     if (!update) {
       return;
     }
 
     var status = readStatusFile(getUpdatesDir());
     pingStateAndStatusCodes(update, false, status);
     var parts = status.split(":");
@@ -4226,72 +4095,57 @@ Checker.prototype = {
     if (UpdateServiceInstance.disabledByPolicy) {
       LOG("Checker: checkForUpdates, disabled by policy");
       return;
     }
     if (!UpdateServiceInstance.canCheckForUpdates && !force) {
       return;
     }
 
-    waitForOtherInstances()
-      .then(() => this.getUpdateURL(force))
-      .then(url => {
-        if (!url) {
-          return;
-        }
-
-        // It's possible that another check was kicked off and that request sent
-        // while we were waiting for other instances to exit here; if the other
-        // instances were closed and also the other check was started during the
-        // same interval between polls, then here we could now be about to start
-        // a second overlapping check, which should not happen. So make sure we
-        // don't have a request already active before we start a new one.
-        if (this._request) {
-          LOG(
-            "Checker: checkForUpdates: check request already active, aborting"
-          );
-          return;
-        }
-
-        this._request = new XMLHttpRequest();
-        this._request.open("GET", url, true);
-        this._request.channel.notificationCallbacks = new CertUtils.BadCertHandler(
-          false
-        );
-        // Prevent the request from reading from the cache.
-        this._request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
-        // Prevent the request from writing to the cache.
-        this._request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
-        // Disable cutting edge features, like TLS 1.3, where middleboxes might brick us
-        this._request.channel.QueryInterface(
-          Ci.nsIHttpChannelInternal
-        ).beConservative = true;
-
-        this._request.overrideMimeType("text/xml");
-        // The Cache-Control header is only interpreted by proxies and the
-        // final destination. It does not help if a resource is already
-        // cached locally.
-        this._request.setRequestHeader("Cache-Control", "no-cache");
-        // HTTP/1.0 servers might not implement Cache-Control and
-        // might only implement Pragma: no-cache
-        this._request.setRequestHeader("Pragma", "no-cache");
-
-        var self = this;
-        this._request.addEventListener("error", function(event) {
-          self.onError(event);
-        });
-        this._request.addEventListener("load", function(event) {
-          self.onLoad(event);
-        });
-
-        LOG("Checker:checkForUpdates - sending request to: " + url);
-        this._request.send(null);
-
-        this._callback = listener;
+    this.getUpdateURL(force).then(url => {
+      if (!url) {
+        return;
+      }
+
+      this._request = new XMLHttpRequest();
+      this._request.open("GET", url, true);
+      this._request.channel.notificationCallbacks = new CertUtils.BadCertHandler(
+        false
+      );
+      // Prevent the request from reading from the cache.
+      this._request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
+      // Prevent the request from writing to the cache.
+      this._request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
+      // Disable cutting edge features, like TLS 1.3, where middleboxes might brick us
+      this._request.channel.QueryInterface(
+        Ci.nsIHttpChannelInternal
+      ).beConservative = true;
+
+      this._request.overrideMimeType("text/xml");
+      // The Cache-Control header is only interpreted by proxies and the
+      // final destination. It does not help if a resource is already
+      // cached locally.
+      this._request.setRequestHeader("Cache-Control", "no-cache");
+      // HTTP/1.0 servers might not implement Cache-Control and
+      // might only implement Pragma: no-cache
+      this._request.setRequestHeader("Pragma", "no-cache");
+
+      var self = this;
+      this._request.addEventListener("error", function(event) {
+        self.onError(event);
       });
+      this._request.addEventListener("load", function(event) {
+        self.onLoad(event);
+      });
+
+      LOG("Checker:checkForUpdates - sending request to: " + url);
+      this._request.send(null);
+
+      this._callback = listener;
+    });
   },
 
   /**
    * Returns an array of nsIUpdate objects discovered by the update check.
    * @throws if the XML document element node name is not updates.
    */
   get _updates() {
     var updatesElement = this._request.responseXML.documentElement;
@@ -5688,17 +5542,17 @@ Downloader.prototype = {
 
     // Do this after *everything* else, since it will likely cause the app
     // to shut down.
     if (shouldShowPrompt) {
       // Wait for language packs to stage before showing any prompt to restart.
       let update = this._update;
       promiseLangPacksUpdated(update).then(() => {
         LOG(
-          "Downloader:onStopRequest - Notifying observers that " +
+          "UpdateManager:refreshUpdateStatus - Notifying observers that " +
             "an update was downloaded. topic: update-downloaded, status: " +
             update.state
         );
         Services.obs.notifyObservers(update, "update-downloaded", update.state);
       });
     }
 
     if (shouldRegisterOnlineObserver) {
--- a/toolkit/mozapps/update/UpdateTelemetry.jsm
+++ b/toolkit/mozapps/update/UpdateTelemetry.jsm
@@ -87,19 +87,16 @@ var AUSTLMY = {
   CHK_ELEVATION_DISABLED_FOR_VERSION: 35,
   // User opted out of elevated updates for the available update version, OSX
   // only (no notification)
   CHK_ELEVATION_OPTOUT_FOR_VERSION: 36,
   // Update checks disabled by enterprise policy
   CHK_DISABLED_BY_POLICY: 37,
   // Update check failed due to write error
   CHK_ERR_WRITE_FAILURE: 38,
-  // Update check was delayed because another instance of the application is
-  // currently running
-  CHK_OTHER_INSTANCE: 39,
 
   /**
    * Submit a telemetry ping for the update check result code or a telemetry
    * ping for a count type histogram count when no update was found. The no
    * update found ping is separate since it is the typical result, is less
    * interesting than the other result codes, and it is easier to analyze the
    * other codes without including it.
    *
--- a/toolkit/mozapps/update/nsIUpdateService.idl
+++ b/toolkit/mozapps/update/nsIUpdateService.idl
@@ -421,45 +421,16 @@ interface nsIUpdateProcessor : nsISuppor
    *        Firefox is unable to fix the permissions itself, it will attempt to
    *        call into the maintenance service to request that it attempt to fix
    *        the permissions.
    */
   void fixUpdateDirectoryPerms(in boolean useServiceOnFailure);
 };
 
 /**
- * Upon creation, which should happen early during startup, the sync manager
- * opens and locks a named semaphore. All other running instances of the same
- * installation of the app also open the same semaphore, so we can use it to
- * determine whether any other instance is running. If so, we'll temporarily
- * hold off on performing update tasks until there are no other instances or
- * until a timeout expires, whichever comes first. That way we can avoid
- * updating behind the back of copies that are still running, so we don't force
- * all running instances to restart (see bug 1366808, where an error was added
- * informing the user of the need to restart any running instances that have
- * been updated).
- */
-[scriptable, uuid(cf4c4487-66d9-4e18-a2e9-39002245332f)]
-interface nsIUpdateSyncManager : nsISupports
-{
-  /**
-   * Returns whether another instance of this application is running.
-   * @returns true if another instance has the semaphore open, false if not
-   */
-  bool isOtherInstanceRunning();
-
-  /**
-   * Should only be used for testing.
-   * Closes and reopens the semaphore, possibly under a different name if the
-   * path hash has changed (which should only happen if a test is forcing it).
-   */
-  void resetSemaphore();
-};
-
-/**
  * An interface describing a global application service that maintains a list
  * of updates previously performed as well as the current active update.
  */
 [scriptable, uuid(0f1098e9-a447-4af9-b030-6f8f35c85f89)]
 interface nsIUpdateManager : nsISupports
 {
   /**
    * Gets the update at the specified index
--- a/toolkit/mozapps/update/tests/browser/head.js
+++ b/toolkit/mozapps/update/tests/browser/head.js
@@ -76,54 +76,16 @@ add_task(async function setupTestCommon(
       [PREF_APP_UPDATE_PROMPTWAITTIME, 3600],
       [PREF_APP_UPDATE_SERVICE_ENABLED, false],
       // Disable activity stream to prevent errors when opening pages during
       // TV runs. See bug 1548422 for an example.
       ["browser.library.activity-stream.enabled", false],
     ],
   });
 
-  // We need to keep the update semaphore from thinking two instances are
-  // running because of the mochitest parent instance, which means we need to
-  // override the directory service with a fake executable path and then reset
-  // the semaphore. But leaving the directory service overridden causes problems
-  // for these tests, so we need to restore the real service immediately after.
-  // To form the path, we'll use the real executable path with a token appended
-  // (the path needs to be absolute, but not to point to a real file).
-  // This block is loosely copied from adjustGeneralPaths() in another update
-  // test file, xpcshellUtilsAUS.js, but this is a much more limited version;
-  // it's been copied here both because the full function is overkill and also
-  // because making it general enough to run in both xpcshell and mochitest
-  // would have been unreasonably difficult.
-  let exePath = Services.dirsvc.get(XRE_EXECUTABLE_FILE, Ci.nsIFile);
-  let dirProvider = {
-    getFile: function AGP_DP_getFile(aProp, aPersistent) {
-      // Set the value of persistent to false so when this directory provider is
-      // unregistered it will revert back to the original provider.
-      aPersistent.value = false;
-      switch (aProp) {
-        case XRE_EXECUTABLE_FILE:
-          exePath.append("browser-test");
-          return exePath;
-      }
-      return null;
-    },
-    QueryInterface: ChromeUtils.generateQI(["nsIDirectoryServiceProvider"]),
-  };
-  let ds = Services.dirsvc.QueryInterface(Ci.nsIDirectoryService);
-  ds.QueryInterface(Ci.nsIProperties).undefine(XRE_EXECUTABLE_FILE);
-  ds.registerProvider(dirProvider);
-
-  let syncManager = Cc["@mozilla.org/updates/update-sync-manager;1"].getService(
-    Ci.nsIUpdateSyncManager
-  );
-  syncManager.resetSemaphore();
-
-  ds.unregisterProvider(dirProvider);
-
   setUpdateTimerPrefs();
   reloadUpdateManagerData(true);
   removeUpdateFiles(true);
   UpdateListener.reset();
   AppMenuNotifications.removeNotification(/.*/);
   // Most app update mochitest-browser-chrome tests expect auto update to be
   // enabled. Those that don't will explicitly change this.
   await setAppUpdateAutoEnabledHelper(true);
@@ -140,23 +102,16 @@ registerCleanupFunction(async () => {
   UpdateListener.reset();
   AppMenuNotifications.removeNotification(/.*/);
   reloadUpdateManagerData(true);
   // Pass false when the log files are needed for troubleshooting the tests.
   removeUpdateFiles(true);
   // Always try to restore the original updater files. If none of the updater
   // backup files are present then this is just a no-op.
   await finishTestRestoreUpdaterBackup();
-  // Reset the update semaphore once again so that we know the semaphore we're
-  // interested in here will be closed properly (normally that happens during
-  // XPCOM shutdown, but that isn't consistent during tests).
-  let syncManager = Cc["@mozilla.org/updates/update-sync-manager;1"].getService(
-    Ci.nsIUpdateSyncManager
-  );
-  syncManager.resetSemaphore();
 });
 
 /**
  * Overrides the add-ons manager language pack staging with a mocked version.
  * The returned promise resolves when language pack staging begins returning an
  * object with the new appVersion and platformVersion and functions to resolve
  * or reject the install.
  */
deleted file mode 100644
--- a/toolkit/mozapps/update/tests/data/semaphoreTestChildScript.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// This is the script that runs in the child xpcshell process for the test
-// unit_aus_update/updateSemaphore.js.
-// The main thing this script does is override the child's directory service
-// so that it ends up with the same fake
-// binary path that the parent test runner has opened its semaphore with.
-// This requires that we have already been passed a constant on our command
-// line which contains the relevant fake binary path, which is called:
-/* global customExePath */
-// We also need this builtin function from xpcshell itself:
-/* global simulateNoScriptActivity */
-
-print("child process is running");
-
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-// This function is copied from xpcshellUtilsAUS.js so that we can have our
-// xpcshell subprocess call it without having to load that whole file, because
-// it turns out that needs a bunch of infrastructure that normally the testing
-// framework would provide, and that also requires a bunch of setup, and it's
-// just not worth all that. This is a cut down version that only includes the
-// directory provider functionality that the subprocess really needs.
-function adjustGeneralPaths() {
-  let dirProvider = {
-    getFile: function AGP_DP_getFile(aProp, aPersistent) {
-      // Set the value of persistent to false so when this directory provider is
-      // unregistered it will revert back to the original provider.
-      aPersistent.value = false;
-      // The semaphore only needs XREExeF, so that's all we provide.
-      if (aProp == "XREExeF") {
-        let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
-        file.initWithPath(customExePath);
-        return file;
-      }
-      return null;
-    },
-    QueryInterface: ChromeUtils.generateQI(["nsIDirectoryServiceProvider"]),
-  };
-  let ds = Services.dirsvc.QueryInterface(Ci.nsIDirectoryService);
-  ds.QueryInterface(Ci.nsIProperties).undefine("XREExeF");
-  ds.registerProvider(dirProvider);
-
-  // Now that we've overridden the directory provider, the name of the update
-  // semaphore needs to be changed to match the overridden path.
-  let syncManager = Cc["@mozilla.org/updates/update-sync-manager;1"].getService(
-    Ci.nsIUpdateSyncManager
-  );
-  syncManager.resetSemaphore();
-}
-
-adjustGeneralPaths();
-
-// Wait a few seconds for the parent to do what it needs to do, then exit.
-print("child process should now have the semaphore; will exit in 5 seconds");
-simulateNoScriptActivity(5);
-print("child process exiting now");
--- a/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
+++ b/toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js
@@ -1614,25 +1614,17 @@ function getSpecialFolderDir(aCSIDL) {
     ctypes.bool /* bool(return) */,
     ctypes.int32_t /* HWND hwndOwner */,
     ctypes.char16_t.ptr /* LPTSTR lpszPath */,
     ctypes.int32_t /* int csidl */,
     ctypes.bool /* BOOL fCreate */
   );
 
   let aryPath = ctypes.char16_t.array()(260);
-  let rv = SHGetSpecialFolderPath(0, aryPath, aCSIDL, false);
-  if (!rv) {
-    do_throw(
-      "SHGetSpecialFolderPath failed to retrieve " +
-        aCSIDL +
-        " with Win32 error " +
-        ctypes.winLastError
-    );
-  }
+  SHGetSpecialFolderPath(0, aryPath, aCSIDL, false);
   lib.close();
 
   let path = aryPath.readString(); // Convert the c-string to js-string
   if (!path) {
     return null;
   }
   debugDump("SHGetSpecialFolderPath returned path: " + path);
   let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
@@ -4349,17 +4341,16 @@ function adjustGeneralPaths() {
       }
       return null;
     },
     QueryInterface: ChromeUtils.generateQI(["nsIDirectoryServiceProvider"]),
   };
   let ds = Services.dirsvc.QueryInterface(Ci.nsIDirectoryService);
   ds.QueryInterface(Ci.nsIProperties).undefine(NS_GRE_DIR);
   ds.QueryInterface(Ci.nsIProperties).undefine(NS_GRE_BIN_DIR);
-  ds.QueryInterface(Ci.nsIProperties).undefine(XRE_EXECUTABLE_FILE);
   ds.registerProvider(dirProvider);
   registerCleanupFunction(function AGP_cleanup() {
     debugDump("start - unregistering directory provider");
 
     if (gAppTimer) {
       debugDump("start - cancel app timer");
       gAppTimer.cancel();
       gAppTimer = null;
@@ -4407,35 +4398,18 @@ function adjustGeneralPaths() {
       } catch (e) {
         debugDump("call to CloseHandle failed, Exception: " + e);
       }
     }
 
     ds.unregisterProvider(dirProvider);
     cleanupTestCommon();
 
-    // Now that our provided is unregistered, reset the semaphore a second time
-    // so that we know the semaphore we're interested in gets unlocked (xpcshell
-    // doesn't always run a proper XPCOM shutdown sequence, which is where that
-    // would normally be happening).
-    let syncManager = Cc[
-      "@mozilla.org/updates/update-sync-manager;1"
-    ].getService(Ci.nsIUpdateSyncManager);
-    syncManager.resetSemaphore();
-
     debugDump("finish - unregistering directory provider");
   });
-
-  // Now that we've overridden the directory provider, the name of the update
-  // semaphore needs to be changed to match the overridden path.
-  debugDump("resetting update semaphore");
-  let syncManager = Cc["@mozilla.org/updates/update-sync-manager;1"].getService(
-    Ci.nsIUpdateSyncManager
-  );
-  syncManager.resetSemaphore();
 }
 
 /**
  * The timer callback to kill the process if it takes too long.
  */
 const gAppTimerCallback = {
   notify: function TC_notify(aTimer) {
     gAppTimer = null;
--- a/toolkit/mozapps/update/tests/moz.build
+++ b/toolkit/mozapps/update/tests/moz.build
@@ -89,17 +89,16 @@ FINAL_TARGET_FILES += [
     "data/partial_log_success_win",
     "data/partial_mac.mar",
     "data/partial_precomplete",
     "data/partial_precomplete_mac",
     "data/partial_removed-files",
     "data/partial_removed-files_mac",
     "data/partial_update_manifest",
     "data/replace_log_success",
-    "data/semaphoreTestChildScript.js",
     "data/simple.mar",
     "TestAUSReadStrings1.ini",
     "TestAUSReadStrings2.ini",
     "TestAUSReadStrings3.ini",
     "TestAUSReadStrings4.ini",
 ]
 
 FINAL_TARGET_PP_FILES += [
deleted file mode 100644
--- a/toolkit/mozapps/update/tests/unit_aus_update/updateSemaphore.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// This test verifies that the update semaphore is working correctly by
-// a) making sure we're the only one that's opened it to begin with, and then
-// b) starting a second copy of the same binary and making sure we can tell we
-//    are no longer the only one that's opened it.
-
-const { Subprocess } = ChromeUtils.import(
-  "resource://gre/modules/Subprocess.jsm"
-);
-
-// Save off the real GRE directory and binary path before we register our
-// mock directory service which overrides them both.
-const thisBinary = Services.dirsvc.get("XREExeF", Ci.nsIFile);
-const greDir = Services.dirsvc.get("GreD", Ci.nsIFile);
-
-add_task(async function() {
-  setupTestCommon();
-
-  // First check that we believe we exclusively hold the semaphore.
-  let syncManager = Cc["@mozilla.org/updates/update-sync-manager;1"].getService(
-    Ci.nsIUpdateSyncManager
-  );
-  Assert.ok(
-    !syncManager.isOtherInstanceRunning(),
-    "no other instance is running yet"
-  );
-
-  // Now start a second copy of this xpcshell binary so that something else
-  // takes the same semaphore. First we'll define its command line.
-  // Most of the child's code is in a separate script file, so all the command
-  // line has to do is set up a few required path strings we need to pass
-  // through to the child, and then include the script file.
-  const args = [
-    "-g",
-    greDir.path,
-    "-e",
-    `
-      const customGreDirPath = "${getApplyDirFile(
-        DIR_RESOURCES
-      ).path.replaceAll("\\", "\\\\")}";
-      const customGreBinDirPath = "${getApplyDirFile(DIR_MACOS).path.replaceAll(
-        "\\",
-        "\\\\"
-      )}";
-      const customExePath = "${getApplyDirFile(
-        DIR_MACOS + FILE_APP_BIN
-      ).path.replaceAll("\\", "\\\\")}";
-      const customUpdDirPath = "${getMockUpdRootD().path.replaceAll(
-        "\\",
-        "\\\\"
-      )}";
-      const customOldUpdDirPath = "${getMockUpdRootD(true).path.replaceAll(
-        "\\",
-        "\\\\"
-      )}";
-    `,
-    "-f",
-    getTestDirFile("semaphoreTestChildScript.js").path,
-  ];
-
-  // Now we can actually invoke the process.
-  debugDump(`launching child process at ${thisBinary.path} with args ${args}`);
-  Subprocess.call({
-    command: thisBinary.path,
-    arguments: args,
-    stderr: "stdout",
-  });
-
-  // It will take the new xpcshell a little time to start up, but we should see
-  // the effect on the semaphore within at most a few seconds.
-  await TestUtils.waitForCondition(
-    () => syncManager.isOtherInstanceRunning(),
-    "waiting for child process to take the semaphore"
-  ).catch(e => {
-    // Rather than throwing out of waitForCondition(), catch and log the failure
-    // manually so that we get output that's a bit more readable.
-    Assert.ok(
-      syncManager.isOtherInstanceRunning(),
-      "child process has the semaphore"
-    );
-  });
-
-  // The semaphore lock should have been closed when the process exited, but
-  // we'll allow a little time for the OS to clean up the handle.
-  await TestUtils.waitForCondition(
-    () => !syncManager.isOtherInstanceRunning(),
-    "waiting for child process to give back the semaphore"
-  ).catch(e => {
-    Assert.ok(
-      !syncManager.isOtherInstanceRunning(),
-      "child process has given back the semaphore"
-    );
-  });
-
-  doTestFinish();
-});
--- a/toolkit/mozapps/update/tests/unit_aus_update/xpcshell.ini
+++ b/toolkit/mozapps/update/tests/unit_aus_update/xpcshell.ini
@@ -31,11 +31,8 @@ support-files =
 [downloadResumeForSameAppVersion.js]
 [languagePackUpdates.js]
 [updateAutoPrefMigrate.js]
 skip-if = os != 'win'
 reason = Update pref migration is currently Windows only
 [updateDirectoryMigrate.js]
 skip-if = os != 'win'
 reason = Update directory migration is currently Windows only
-[updateSemaphore.js]
-skip-if = os == 'mac'
-reason = The semaphore isn't implemented for Mac
deleted file mode 100644
--- a/toolkit/xre/GlobalSemaphore.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "GlobalSemaphore.h"
-
-#include "commonupdatedir.h"  // for GetInstallHash
-#include "mozilla/UniquePtr.h"
-#include "updatedefines.h"  // for NS_t* definitions
-
-#ifndef XP_WIN
-#  include <fcntl.h>     // for O_CREAT
-#  include <sys/stat.h>  // for mode constants
-#else
-#  include <limits.h>  // for _XOPEN_PATH_MAX / _POSIX_PATH_MAX
-#endif
-
-#ifdef XP_WIN
-#  define SEMAPHORE_NAME_PREFIX "Global\\"
-#else
-#  define SEMAPHORE_NAME_PREFIX "/"
-#endif
-
-namespace mozilla {
-
-// Prevent this function failing the build for being unused on Mac.
-#ifndef XP_MACOSX
-
-static bool GetSemaphoreName(const char* nameToken, const char16_t* installPath,
-                             mozilla::UniquePtr<NS_tchar[]>& semName) {
-  mozilla::UniquePtr<NS_tchar[]> pathHash;
-  if (!GetInstallHash(installPath, MOZ_APP_VENDOR, pathHash)) {
-    return false;
-  }
-
-  size_t semNameLen = strlen(SEMAPHORE_NAME_PREFIX) + strlen(nameToken) +
-                      NS_tstrlen(pathHash.get()) + 1;
-  semName = mozilla::MakeUnique<NS_tchar[]>(semNameLen + 1);
-  if (!semName) {
-    return false;
-  }
-
-// On Windows, we need to convert the token string to UTF-16.
-// printf can do that for us, but we need to tell it to by changing the type
-// indicator in the format string.
-// We also need different prefixes to the semaphore name, because it's a
-// path-like string and because Windows has the "global" concept.
-#  ifdef XP_WIN
-  const NS_tchar* kSemaphoreNameFormat = NS_T(SEMAPHORE_NAME_PREFIX "%S-%s");
-#  else
-  const NS_tchar* kSemaphoreNameFormat = NS_T(SEMAPHORE_NAME_PREFIX "%s-%s");
-#  endif
-
-  NS_tsnprintf(semName.get(), semNameLen + 1, kSemaphoreNameFormat, nameToken,
-               pathHash.get());
-
-  return true;
-}
-
-#endif
-
-#ifdef XP_WIN
-
-GlobalSemHandle OpenGlobalSemaphore(const char* nameToken,
-                                    const char16_t* installPath) {
-  mozilla::UniquePtr<NS_tchar[]> semName;
-  if (!GetSemaphoreName(nameToken, installPath, semName)) {
-    return nullptr;
-  }
-
-  // Initialize the semaphore to LONG_MAX because we're not actually using it
-  // to control access to any limited resource, we just want to know how many
-  // times the semaphore is taken. And taking a semaphore decrements it, so we
-  // have to start at the top of the range instead of at zero.
-  GlobalSemHandle sem =
-      ::CreateSemaphoreW(nullptr, LONG_MAX, LONG_MAX, semName.get());
-  if (sem) {
-    // Claim a reference to the semaphore. After this point, the semaphore count
-    // should always be LONG_MAX - [number of running instances].
-    if (::WaitForSingleObject(sem, 0) != WAIT_OBJECT_0) {
-      // Either there are LONG_MAX instances running or something is wrong and
-      // this semaphore is not usable.
-      ::CloseHandle(sem);
-      sem = nullptr;
-    }
-  }
-  return sem;
-}
-
-void ReleaseGlobalSemaphore(GlobalSemHandle sem) {
-  if (sem) {
-    ::ReleaseSemaphore(sem, 1, nullptr);
-    ::CloseHandle(sem);
-  }
-}
-
-bool IsOtherInstanceRunning(GlobalSemHandle sem, bool* aResult) {
-  // There's no documented way to get a semaphore's current count except to
-  // wait on it (which decrements it) and then release it (which increments it
-  // back and returns the pre-incremented count), so that's what we'll do. There
-  // is also NtQuerySemaphore, but using the native API doesn't seem worth the
-  // trouble here.
-  if (sem && ::WaitForSingleObject(sem, 0) == WAIT_OBJECT_0) {
-    LONG count = 0;
-    if (::ReleaseSemaphore(sem, 1, &count)) {
-      // At rest, the count is (LONG_MAX - [number of running instances]), but
-      // the count we read had been
-      // decremented once more by the Wait call here, so we need to compare
-      // against one less than that to see if there's exactly one instance
-      // running.
-      *aResult = (count != (LONG_MAX - 2));
-      return true;
-    }
-  }
-
-  return false;
-}
-
-#elif defined(XP_MACOSX)
-
-// We don't actually have Mac support here, because sem_getvalue isn't supported
-// there (the header calls it deprecated, but actually it's just unimplemented),
-// and there is no other way to get the value of a POSIX-semaphore. We'll have
-// to do something platform-specific.
-
-GlobalSemHandle OpenGlobalSemaphore(const char* /* unused */,
-                                    const char16_t* /* unused */) {
-  // Return something that isn't a valid pointer, but that the manager won't
-  // think represents a failure.
-  return (GlobalSemHandle)1;
-}
-
-void ReleaseGlobalSemaphore(GlobalSemHandle /* unused */) {}
-
-bool IsOtherInstanceRunning(GlobalSemHandle /* unused */, bool* aResult) {
-  *aResult = false;
-  return true;
-}
-
-#else  // Neither Windows nor Mac
-
-GlobalSemHandle OpenGlobalSemaphore(const char* nameToken,
-                                    const char16_t* installPath) {
-  mozilla::UniquePtr<NS_tchar[]> semName;
-  if (!GetSemaphoreName(nameToken, installPath, semName)) {
-    return nullptr;
-  }
-
-  // Initialize the semaphore to the maximum value because we don't actually
-  // want to limit the number of instances, and assign all permissions because
-  // we also don't want to lock out any other users. The update service has
-  // protections to prevent problems resulting from this semaphore
-  // being messed with by an attacker.
-  GlobalSemHandle sem = sem_open(semName.get(), O_CREAT,
-                                 S_IRWXU | S_IRWXG | S_IRWXO, SEM_VALUE_MAX);
-  if (sem == SEM_FAILED) {
-    return nullptr;
-  }
-
-  // Decrement the semaphore whether we created it or opened it. This way the
-  // count is always SEM_VALUE_MAX - [number of running instances].
-  if (sem_trywait(sem)) {
-    // Either there are SEM_VALUE_MAX instances running or something is wrong
-    // and this semaphore is not usable.
-    sem_close(sem);
-    return nullptr;
-  }
-
-  return sem;
-}
-
-void ReleaseGlobalSemaphore(GlobalSemHandle sem) {
-  if (sem) {
-    sem_post(sem);
-    sem_close(sem);
-  }
-}
-
-bool IsOtherInstanceRunning(GlobalSemHandle sem, bool* aResult) {
-  int value = 0;
-  if (sem && !sem_getvalue(sem, &value)) {
-    // Zero and negative values are all error states.
-    if (value <= 0) {
-      return false;
-    }
-    *aResult = (value != (SEM_VALUE_MAX - 1));
-    return true;
-  }
-  return false;
-}
-
-#endif
-
-};  // namespace mozilla
deleted file mode 100644
--- a/toolkit/xre/GlobalSemaphore.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef GLOBALSEMAPHORE_H
-#define GLOBALSEMAPHORE_H
-
-namespace mozilla {
-
-#ifdef XP_WIN
-#  include <windows.h>
-using GlobalSemHandle = HANDLE;
-#else
-#  include <semaphore.h>
-using GlobalSemHandle = sem_t*;
-#endif
-
-/*
- * nameToken should be a string very briefly naming the semaphore you are
- * creating, and it should be unique systemwide except for across multiple
- * instances of the same application.
- * installPath should be the path to the directory containing the application.
- *
- * Taken together, those two parameters will be used to form a string which is
- * unique to this copy of this application.
- * Creating the semaphore will fail if the final string (the token plus the path
- * hash) is longer than the platform's maximum. On Windows that's MAX_PATH, on
- * POSIX systems it's either _POSIX_PATH_MAX or perhaps SEM_NAME_LEN.
- *
- * Returns nullptr upon failure, on all platforms.
- */
-GlobalSemHandle OpenGlobalSemaphore(const char* nameToken,
-                                    const char16_t* installPath);
-
-void ReleaseGlobalSemaphore(GlobalSemHandle sem);
-
-// aResult will be set to true if another instance *was* found, false if not.
-// Return value is true on success, false on error (and aResult won't be set).
-bool IsOtherInstanceRunning(GlobalSemHandle sem, bool* aResult);
-
-};  // namespace mozilla
-
-#endif  // GLOBALEMAPHORE_H
--- a/toolkit/xre/moz.build
+++ b/toolkit/xre/moz.build
@@ -33,17 +33,16 @@ EXPORTS += [
     "nsAppRunner.h",
     "nsIAppStartupNotifier.h",
 ]
 
 EXPORTS.mozilla += [
     "AutoSQLiteLifetime.h",
     "Bootstrap.h",
     "CmdLineAndEnvUtils.h",
-    "GlobalSemaphore.h",
     "SafeMode.h",
     "UntrustedModulesData.h",
 ]
 
 if CONFIG["MOZ_INSTRUMENT_EVENT_LOOP"]:
     EXPORTS += ["EventTracer.h"]
 
 if CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
@@ -121,21 +120,16 @@ if CONFIG["MOZ_X11"]:
         "nsX11ErrorHandler.cpp",
     ]
 
 if CONFIG["MOZ_WIDGET_TOOLKIT"] == "android":
     UNIFIED_SOURCES += [
         "nsAndroidStartup.cpp",
     ]
 
-if CONFIG["MOZ_WIDGET_TOOLKIT"] != "android":
-    UNIFIED_SOURCES += [
-        "GlobalSemaphore.cpp",
-    ]
-
 UNIFIED_SOURCES += [
     "/toolkit/mozapps/update/common/commonupdatedir.cpp",
     "AutoSQLiteLifetime.cpp",
     "Bootstrap.cpp",
     "CmdLineAndEnvUtils.cpp",
     "CreateAppData.cpp",
     "nsAppStartupNotifier.cpp",
     "nsConsoleWriter.cpp",
@@ -164,17 +158,16 @@ if CONFIG["MOZ_INSTRUMENT_EVENT_LOOP"]:
     UNIFIED_SOURCES += [
         "EventTracer.cpp",
     ]
 
 if CONFIG["MOZ_UPDATER"]:
     if CONFIG["MOZ_WIDGET_TOOLKIT"] != "android":
         UNIFIED_SOURCES += [
             "nsUpdateDriver.cpp",
-            "nsUpdateSyncManager.cpp",
         ]
 
 if CONFIG["MOZ_PDF_PRINTING"]:
     DEFINES["PROXY_PRINTING"] = 1
     LOCAL_INCLUDES += [
         "../components/printingui",
     ]
 
--- a/toolkit/xre/nsAppStartupNotifier.cpp
+++ b/toolkit/xre/nsAppStartupNotifier.cpp
@@ -1,25 +1,21 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsAppStartupNotifier.h"
-#include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsICategoryManager.h"
-#include "nsIObserver.h"
 #include "nsXPCOM.h"
+#include "nsAppStartupNotifier.h"
 #include "mozilla/SimpleEnumerator.h"
 
-using namespace mozilla;
-
 /* static */
 nsresult nsAppStartupNotifier::NotifyObservers(const char* aCategory) {
   NS_ENSURE_ARG(aCategory);
   nsresult rv;
 
   // now initialize all startup listeners
   nsCOMPtr<nsICategoryManager> categoryManager =
       do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
--- a/toolkit/xre/nsAppStartupNotifier.h
+++ b/toolkit/xre/nsAppStartupNotifier.h
@@ -2,16 +2,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsAppStartupNotifier_h___
 #define nsAppStartupNotifier_h___
 
 #include "nsIAppStartupNotifier.h"
-#include "nsError.h"
 
 class nsAppStartupNotifier final {
  public:
   static nsresult NotifyObservers(const char* aTopic);
 };
 
 #endif /* nsAppStartupNotifier_h___ */
--- a/toolkit/xre/nsUpdateDriver.cpp
+++ b/toolkit/xre/nsUpdateDriver.cpp
@@ -50,20 +50,16 @@
 #elif defined(XP_UNIX)
 #  include <unistd.h>
 #  include <sys/wait.h>
 #endif
 
 using namespace mozilla;
 
 static LazyLogModule sUpdateLog("updatedriver");
-// Some other file in our unified batch might have defined LOG already.
-#ifdef LOG
-#  undef LOG
-#endif
 #define LOG(args) MOZ_LOG(sUpdateLog, mozilla::LogLevel::Debug, args)
 
 #ifdef XP_WIN
 #  define UPDATER_BIN "updater.exe"
 #  define MAINTENANCE_SVC_NAME L"MozillaMaintenance"
 #elif XP_MACOSX
 #  define UPDATER_APP "updater.app"
 #  define UPDATER_BIN "org.mozilla.updater"
deleted file mode 100644
--- a/toolkit/xre/nsUpdateSyncManager.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsUpdateSyncManager.h"
-
-#include "mozilla/Unused.h"
-#include "mozilla/Services.h"
-#include "nsComponentManagerUtils.h"
-#include "nsCRT.h"
-#include "nsIFile.h"
-#include "nsIObserverService.h"
-#include "nsIProperties.h"
-#include "nsString.h"
-#include "nsXULAppAPI.h"
-
-#define UPDATE_SEMAPHORE_NAME_TOKEN "MozillaUpdateSemaphore"
-
-nsUpdateSyncManager* gUpdateSyncManager = nullptr;
-
-NS_IMPL_ISUPPORTS(nsUpdateSyncManager, nsIUpdateSyncManager, nsIObserver)
-
-nsUpdateSyncManager::nsUpdateSyncManager() { OpenSemaphore(); }
-
-nsUpdateSyncManager::~nsUpdateSyncManager() {
-  ReleaseSemaphore();
-  gUpdateSyncManager = nullptr;
-}
-
-already_AddRefed<nsUpdateSyncManager> nsUpdateSyncManager::GetSingleton() {
-  if (!gUpdateSyncManager) {
-    gUpdateSyncManager = new nsUpdateSyncManager();
-  }
-  return do_AddRef(gUpdateSyncManager);
-}
-
-NS_IMETHODIMP nsUpdateSyncManager::Observe(nsISupports* aSubject,
-                                           const char* aTopic,
-                                           const char16_t* aData) {
-  mozilla::Unused << aSubject;
-  mozilla::Unused << aData;
-
-  // We want to hold the semaphore for as much of the lifetime of the app
-  // as we can, so we observe xpcom-startup so we get constructed as early as
-  // possible, which triggers constructing the singleton.
-  if (!nsCRT::strcmp(aTopic, NS_XPCOM_STARTUP_OBSERVER_ID)) {
-    nsCOMPtr<nsIObserverService> observerService =
-        mozilla::services::GetObserverService();
-    if (observerService) {
-      return observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
-                                          false);
-    }
-    return NS_ERROR_SERVICE_NOT_AVAILABLE;
-  }
-  if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
-    ReleaseSemaphore();
-  }
-
-  return NS_OK;
-}
-
-nsresult nsUpdateSyncManager::OpenSemaphore() {
-  if (mSemaphore) {
-    // Semaphore is already open.
-    return NS_OK;
-  }
-
-  // Only open the semaphore from the browser process.
-  // Our component registration should already have made sure of this.
-  if (NS_WARN_IF(XRE_GetProcessType() != GeckoProcessType_Default)) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIProperties> dirSvc =
-      do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
-  NS_ENSURE_TRUE(dirSvc, NS_ERROR_SERVICE_NOT_AVAILABLE);
-
-  nsCOMPtr<nsIFile> appFile;
-  nsresult rv = dirSvc->Get(XRE_EXECUTABLE_FILE, NS_GET_IID(nsIFile),
-                            getter_AddRefs(appFile));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIFile> appDirFile;
-  rv = appFile->GetParent(getter_AddRefs(appDirFile));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString appDirPath;
-  rv = appDirFile->GetPath(appDirPath);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mSemaphore = mozilla::OpenGlobalSemaphore(
-      UPDATE_SEMAPHORE_NAME_TOKEN, PromiseFlatString(appDirPath).get());
-  NS_ENSURE_TRUE(mSemaphore, NS_ERROR_FAILURE);
-
-  return NS_OK;
-}
-
-void nsUpdateSyncManager::ReleaseSemaphore() {
-  if (!mSemaphore) {
-    // Semaphore is already released.
-    return;
-  }
-
-  mozilla::ReleaseGlobalSemaphore(mSemaphore);
-  mSemaphore = nullptr;
-}
-
-NS_IMETHODIMP nsUpdateSyncManager::IsOtherInstanceRunning(bool* aResult) {
-  if (NS_WARN_IF(XRE_GetProcessType() != GeckoProcessType_Default)) {
-    return NS_ERROR_SERVICE_NOT_AVAILABLE;
-  }
-
-  if (!mSemaphore) {
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  bool rv = mozilla::IsOtherInstanceRunning(mSemaphore, aResult);
-  NS_ENSURE_TRUE(rv, NS_ERROR_FAILURE);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsUpdateSyncManager::ResetSemaphore() {
-  ReleaseSemaphore();
-  return OpenSemaphore();
-}
deleted file mode 100644
--- a/toolkit/xre/nsUpdateSyncManager.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsUpdateSyncManager_h__
-#define nsUpdateSyncManager_h__
-
-#include "mozilla/AlreadyAddRefed.h"
-#include "nsIObserver.h"
-#include "nsIUpdateService.h"
-#include "GlobalSemaphore.h"
-
-// The update sync manager is responsible for making sure that only one
-// instance of the application is running at the time we want to start updating
-// it. It does this by taking a semaphore very early during the application's
-// startup process. Then, when app update tasks are ready to run, the update
-// service asks us whether anything else has also taken the semaphore, which,
-// if true, would mean another instance of the application is currently running
-// and performing update tasks should be avoided (the update service also runs
-// a timeout and eventually goes ahead with the update in order to prevent an
-// external program from effectively disabling updates).
-// The immediately obvious tool for this job would be a mutex and not a
-// semaphore, since only one instance can be applying updates at a time, but at
-// it turns out that wouldn't quite meet the requirements. Consider this
-// scenario: an application instance we'll call instance A runs and takes the
-// mutex. It doesn't check for updates right away. A second instance called B
-// then starts and cannot get the mutex during its startup because instance A
-// still holds it. A third instance C is started and has the same problem. Now,
-// what if instance A exits? It returns the mutex, so if either B or C decide to
-// check for updates they'll be able to take it. But neither is aware of the
-// other's existence, so whichever one wins that race will be able to apply an
-// update behind the other one's back, which is the exact thing this component
-// is intended to prevent. By using a semaphore instead, every instance is
-// always aware of how many other instances are running by checking the
-// semaphore's count, and this problem is avoided.
-class nsUpdateSyncManager final : public nsIUpdateSyncManager,
-                                  public nsIObserver {
- public:
-  nsUpdateSyncManager();
-
-  NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSIUPDATESYNCMANAGER
-  NS_DECL_NSIOBSERVER
-
-  static already_AddRefed<nsUpdateSyncManager> GetSingleton();
-
- private:
-  ~nsUpdateSyncManager();
-
-  nsUpdateSyncManager(nsUpdateSyncManager&) = delete;
-  nsUpdateSyncManager(nsUpdateSyncManager&&) = delete;
-  nsUpdateSyncManager& operator=(nsUpdateSyncManager&) = delete;
-  nsUpdateSyncManager& operator=(nsUpdateSyncManager&&) = delete;
-
-  nsresult OpenSemaphore();
-  void ReleaseSemaphore();
-
-  mozilla::GlobalSemHandle mSemaphore = nullptr;
-};
-
-#endif  // nsUpdateSyncManager_h__