Bug 1355161 - script-generated patch to replace .{currentThread,mainThread}.dispatch(..., Ci.nsIThread.DISPATCH_NORMAL) with .dispatchToMainThread(...), r=froydnj.
authorFlorian Queze <florian@queze.net>
Fri, 14 Apr 2017 18:29:12 +0200
changeset 563292 cd981920d0ef8adf66e504b718a4208dc03c7a4c
parent 563291 d2a26a27c192d43ffec287c618a9926ba0a75d67
child 563334 d65b53cf8fd9f7747c7ee4e3ea96f12434917daa
child 563371 3f319382720cc8fa8257b25b7513546e6113791e
push id54258
push usercpeterson@mozilla.com
push dateSun, 16 Apr 2017 05:52:14 +0000
reviewersfroydnj
bugs1355161
milestone55.0a1
Bug 1355161 - script-generated patch to replace .{currentThread,mainThread}.dispatch(..., Ci.nsIThread.DISPATCH_NORMAL) with .dispatchToMainThread(...), r=froydnj.
addon-sdk/source/lib/sdk/timers.js
addon-sdk/source/modules/system/Startup.js
addon-sdk/source/test/addons/content-permissions/httpd.js
addon-sdk/source/test/addons/content-script-messages-latency/httpd.js
addon-sdk/source/test/addons/e10s-content/lib/httpd.js
addon-sdk/source/test/addons/places/lib/httpd.js
addon-sdk/source/test/lib/httpd.js
b2g/components/ErrorPage.jsm
browser/base/content/browser-fullZoom.js
browser/base/content/test/tabPrompts/browser_multiplePrompts.js
browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js
browser/components/customizableui/CustomizeMode.jsm
browser/components/downloads/content/allDownloadsViewOverlay.js
browser/components/extensions/ext-utils.js
browser/components/migration/MigrationUtils.jsm
browser/components/nsBrowserGlue.js
browser/components/search/content/search.xml
browser/components/sessionstore/test/content.js
browser/experiments/test/addons/experiment-racybranch/bootstrap.js
browser/modules/SocialService.jsm
browser/modules/webrtcUI.jsm
devtools/client/debugger/new/debugger.js
devtools/client/debugger/new/integration-tests.js
devtools/client/debugger/views/global-search-view.js
devtools/client/shared/DOMHelpers.jsm
devtools/client/shared/widgets/VariablesView.jsm
devtools/server/actors/tab.js
devtools/server/actors/webbrowser.js
devtools/server/actors/webextension-inspected-window.js
devtools/server/tests/unit/head_dbg.js
devtools/server/tests/unit/test_blackboxing-05.js
devtools/server/tests/unit/test_nsjsinspector.js
devtools/server/tests/unit/test_stepping-06.js
devtools/shared/DevToolsUtils.js
devtools/shared/transport/stream-utils.js
dom/base/IndexedDBHelper.jsm
dom/base/test/file_simplecontentpolicy.js
dom/browser-element/BrowserElementPromptService.jsm
dom/notification/NotificationStorage.js
dom/presentation/provider/PresentationControlService.js
dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js
dom/presentation/tests/xpcshell/test_multicast_dns_device_provider.js
dom/system/gonk/DataCallManager.js
dom/system/gonk/NetworkService.js
dom/system/gonk/TetheringService.js
js/xpconnect/tests/unit/head_ongc.js
js/xpconnect/tests/unit/head_watchdog.js
mobile/android/components/PromptService.js
mobile/android/components/extensions/ext-utils.js
mobile/android/modules/MediaPlayerApp.jsm
mobile/android/tests/browser/chrome/test_awsy_lite.html
mobile/android/tests/browser/chrome/test_video_discovery.html
mobile/android/tests/browser/robocop/robocop_head.js
mobile/android/tests/browser/robocop/testBrowserDiscovery.js
mobile/android/tests/browser/robocop/testHistoryService.js
mobile/android/tests/browser/robocop/testTrackingProtection.js
mobile/android/tests/browser/robocop/testVideoControls.js
netwerk/test/browser/browser_nsIFormPOSTActionChannel.js
netwerk/test/httpserver/test/test_async_response_sending.js
netwerk/test/httpserver/test/test_processasync.js
netwerk/test/httpserver/test/test_seizepower.js
services/common/utils.js
services/fxaccounts/Credentials.jsm
services/sync/modules/SyncedTabs.jsm
services/sync/tps/extensions/mozmill/resource/stdlib/httpd.js
testing/mochitest/browser-harness.xul
testing/mochitest/browser-test.js
testing/modules/TestUtils.jsm
testing/specialpowers/content/specialpowersAPI.js
testing/xpcshell/head.js
toolkit/components/addoncompat/RemoteAddonsChild.jsm
toolkit/components/addoncompat/tests/addon/bootstrap.js
toolkit/components/contentprefs/ContentPrefService2.jsm
toolkit/components/contentprefs/nsContentPrefService.js
toolkit/components/filepicker/nsFilePicker.js
toolkit/components/formautofill/FormAutofillContentService.js
toolkit/components/passwordmgr/nsLoginManagerPrompter.js
toolkit/components/perfmonitoring/PerformanceWatcher.jsm
toolkit/components/places/PlacesUtils.jsm
toolkit/components/places/nsLivemarkService.js
toolkit/components/places/tests/bookmarks/test_async_observers.js
toolkit/components/prompts/content/tabprompts.xml
toolkit/components/search/nsSearchService.js
toolkit/components/telemetry/TelemetrySession.jsm
toolkit/components/telemetry/tests/unit/head.js
toolkit/components/telemetry/tests/unit/test_PingSender.js
toolkit/components/thumbnails/BackgroundPageThumbs.jsm
toolkit/components/url-classifier/nsUrlClassifierHashCompleter.js
toolkit/content/browser-content.js
toolkit/content/contentAreaUtils.js
toolkit/content/widgets/remote-browser.xml
toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js
toolkit/modules/PropertyListUtils.jsm
toolkit/modules/Troubleshoot.jsm
toolkit/modules/addons/WebRequest.jsm
toolkit/modules/tests/xpcshell/test_task.js
toolkit/mozapps/downloads/DownloadLastDir.jsm
toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedRecovery.js
xpcom/tests/unit/test_bug656331.js
--- a/addon-sdk/source/lib/sdk/timers.js
+++ b/addon-sdk/source/lib/sdk/timers.js
@@ -75,18 +75,17 @@ var dispatcher = _ => {
 
 function setImmediate(callback, ...params) {
   let id = ++ lastID;
   // register new immediate timer with curried params.
   immediates.set(id, _ => callback.apply(callback, params));
   // if dispatch loop is not scheduled schedule one. Own scheduler
   if (!dispatcher.scheduled) {
     dispatcher.scheduled = true;
-    threadManager.currentThread.dispatch(dispatcher,
-                                         Ci.nsIThread.DISPATCH_NORMAL);
+    threadManager.dispatchToMainThread(dispatcher);
   }
   return id;
 }
 
 function clearImmediate(id) {
   immediates.delete(id);
 }
 
--- a/addon-sdk/source/modules/system/Startup.js
+++ b/addon-sdk/source/modules/system/Startup.js
@@ -44,14 +44,13 @@ else {
       appStartup = NAME2TOPIC[name];
       break;
     }
   }
 
   let listener = function (subject, topic) {
     Services.obs.removeObserver(this, topic);
     Startup.initialized = true;
-    Services.tm.currentThread.dispatch(() => gOnceInitializedDeferred.resolve(),
-                                       Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(() => gOnceInitializedDeferred.resolve());
   }
 
   Services.obs.addObserver(listener, appStartup);
 }
--- a/addon-sdk/source/test/addons/content-permissions/httpd.js
+++ b/addon-sdk/source/test/addons/content-permissions/httpd.js
@@ -451,18 +451,17 @@ nsHttpServer.prototype =
       var stopEvent =
         {
           run: function()
           {
             dumpn("*** _notifyStopped async callback");
             self._notifyStopped();
           }
         };
-      gThreadManager.currentThread
-                    .dispatch(stopEvent, Ci.nsIThread.DISPATCH_NORMAL);
+      gThreadManager.dispatchToMainThread(stopEvent);
     }
   },
 
   // NSIHTTPSERVER
 
   //
   // see nsIHttpServer.start
   //
@@ -2690,18 +2689,17 @@ ServerHandler.prototype =
       catch (e)
       {
         fis.close();
         throw e;
       }
 
       let writeMore = function writeMore()
       {
-        gThreadManager.currentThread
-                      .dispatch(writeData, Ci.nsIThread.DISPATCH_NORMAL);
+        gThreadManager.dispatchToMainThread(writeData);
       }
 
       var input = new BinaryInputStream(fis);
       var output = new BinaryOutputStream(response.bodyOutputStream);
       var writeData =
         {
           run: function()
           {
@@ -3762,23 +3760,23 @@ Response.prototype =
       // happening asynchronously with respect to the actual writing of data to
       // bodyOutputStream, as they currently do; if they happened synchronously,
       // an event which ran before this one could write more data to the
       // response body before we get around to canceling the copier. We have
       // tests for this in test_seizepower.js, however, and I can't think of a
       // way to handle both cases without removing bodyOutputStream access and
       // moving its effective write(data, length) method onto Response, which
       // would be slower and require more code than this anyway.
-      gThreadManager.currentThread.dispatch({
+      gThreadManager.dispatchToMainThread({
         run: function()
         {
           dumpn("*** canceling copy asynchronously...");
           copier.cancel(Cr.NS_ERROR_UNEXPECTED);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     }
     else
     {
       this.end();
     }
   },
 
   /**
@@ -4517,17 +4515,17 @@ WriteThroughCopier.prototype =
           {
             NS_ASSERT(false,
                       "how are we throwing an exception here? we control " +
                       "all the callers! " + e);
           }
         }
       };
 
-    gThreadManager.currentThread.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
+    gThreadManager.dispatchToMainThread(event);
   },
 
   /**
 * Kicks off another wait for more data to be available from the input stream.
 */
   _waitToReadData: function()
   {
     dumpn("*** _waitToReadData");
--- a/addon-sdk/source/test/addons/content-script-messages-latency/httpd.js
+++ b/addon-sdk/source/test/addons/content-script-messages-latency/httpd.js
@@ -451,18 +451,17 @@ nsHttpServer.prototype =
       var stopEvent =
         {
           run: function()
           {
             dumpn("*** _notifyStopped async callback");
             self._notifyStopped();
           }
         };
-      gThreadManager.currentThread
-                    .dispatch(stopEvent, Ci.nsIThread.DISPATCH_NORMAL);
+      gThreadManager.dispatchToMainThread(stopEvent);
     }
   },
 
   // NSIHTTPSERVER
 
   //
   // see nsIHttpServer.start
   //
@@ -2690,18 +2689,17 @@ ServerHandler.prototype =
       catch (e)
       {
         fis.close();
         throw e;
       }
 
       let writeMore = function writeMore()
       {
-        gThreadManager.currentThread
-                      .dispatch(writeData, Ci.nsIThread.DISPATCH_NORMAL);
+        gThreadManager.dispatchToMainThread(writeData);
       }
 
       var input = new BinaryInputStream(fis);
       var output = new BinaryOutputStream(response.bodyOutputStream);
       var writeData =
         {
           run: function()
           {
@@ -3762,23 +3760,23 @@ Response.prototype =
       // happening asynchronously with respect to the actual writing of data to
       // bodyOutputStream, as they currently do; if they happened synchronously,
       // an event which ran before this one could write more data to the
       // response body before we get around to canceling the copier. We have
       // tests for this in test_seizepower.js, however, and I can't think of a
       // way to handle both cases without removing bodyOutputStream access and
       // moving its effective write(data, length) method onto Response, which
       // would be slower and require more code than this anyway.
-      gThreadManager.currentThread.dispatch({
+      gThreadManager.dispatchToMainThread({
         run: function()
         {
           dumpn("*** canceling copy asynchronously...");
           copier.cancel(Cr.NS_ERROR_UNEXPECTED);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     }
     else
     {
       this.end();
     }
   },
 
   /**
@@ -4517,17 +4515,17 @@ WriteThroughCopier.prototype =
           {
             NS_ASSERT(false,
                       "how are we throwing an exception here? we control " +
                       "all the callers! " + e);
           }
         }
       };
 
-    gThreadManager.currentThread.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
+    gThreadManager.dispatchToMainThread(event);
   },
 
   /**
 * Kicks off another wait for more data to be available from the input stream.
 */
   _waitToReadData: function()
   {
     dumpn("*** _waitToReadData");
--- a/addon-sdk/source/test/addons/e10s-content/lib/httpd.js
+++ b/addon-sdk/source/test/addons/e10s-content/lib/httpd.js
@@ -452,18 +452,17 @@ nsHttpServer.prototype =
       var stopEvent =
         {
           run: function()
           {
             dumpn("*** _notifyStopped async callback");
             self._notifyStopped();
           }
         };
-      gThreadManager.currentThread
-                    .dispatch(stopEvent, Ci.nsIThread.DISPATCH_NORMAL);
+      gThreadManager.dispatchToMainThread(stopEvent);
     }
   },
 
   // NSIHTTPSERVER
 
   //
   // see nsIHttpServer.start
   //
@@ -2691,18 +2690,17 @@ ServerHandler.prototype =
       catch (e)
       {
         fis.close();
         throw e;
       }
 
       let writeMore = function writeMore()
       {
-        gThreadManager.currentThread
-                      .dispatch(writeData, Ci.nsIThread.DISPATCH_NORMAL);
+        gThreadManager.dispatchToMainThread(writeData);
       }
 
       var input = new BinaryInputStream(fis);
       var output = new BinaryOutputStream(response.bodyOutputStream);
       var writeData =
         {
           run: function()
           {
@@ -3763,23 +3761,23 @@ Response.prototype =
       // happening asynchronously with respect to the actual writing of data to
       // bodyOutputStream, as they currently do; if they happened synchronously,
       // an event which ran before this one could write more data to the
       // response body before we get around to canceling the copier. We have
       // tests for this in test_seizepower.js, however, and I can't think of a
       // way to handle both cases without removing bodyOutputStream access and
       // moving its effective write(data, length) method onto Response, which
       // would be slower and require more code than this anyway.
-      gThreadManager.currentThread.dispatch({
+      gThreadManager.dispatchToMainThread({
         run: function()
         {
           dumpn("*** canceling copy asynchronously...");
           copier.cancel(Cr.NS_ERROR_UNEXPECTED);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     }
     else
     {
       this.end();
     }
   },
 
   /**
@@ -4518,17 +4516,17 @@ WriteThroughCopier.prototype =
           {
             NS_ASSERT(false,
                       "how are we throwing an exception here? we control " +
                       "all the callers! " + e);
           }
         }
       };
 
-    gThreadManager.currentThread.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
+    gThreadManager.dispatchToMainThread(event);
   },
 
   /**
 * Kicks off another wait for more data to be available from the input stream.
 */
   _waitToReadData: function()
   {
     dumpn("*** _waitToReadData");
--- a/addon-sdk/source/test/addons/places/lib/httpd.js
+++ b/addon-sdk/source/test/addons/places/lib/httpd.js
@@ -451,18 +451,17 @@ nsHttpServer.prototype =
       var stopEvent =
         {
           run: function()
           {
             dumpn("*** _notifyStopped async callback");
             self._notifyStopped();
           }
         };
-      gThreadManager.currentThread
-                    .dispatch(stopEvent, Ci.nsIThread.DISPATCH_NORMAL);
+      gThreadManager.dispatchToMainThread(stopEvent);
     }
   },
 
   // NSIHTTPSERVER
 
   //
   // see nsIHttpServer.start
   //
@@ -2690,18 +2689,17 @@ ServerHandler.prototype =
       catch (e)
       {
         fis.close();
         throw e;
       }
 
       let writeMore = function writeMore()
       {
-        gThreadManager.currentThread
-                      .dispatch(writeData, Ci.nsIThread.DISPATCH_NORMAL);
+        gThreadManager.dispatchToMainThread(writeData);
       }
 
       var input = new BinaryInputStream(fis);
       var output = new BinaryOutputStream(response.bodyOutputStream);
       var writeData =
         {
           run: function()
           {
@@ -3762,23 +3760,23 @@ Response.prototype =
       // happening asynchronously with respect to the actual writing of data to
       // bodyOutputStream, as they currently do; if they happened synchronously,
       // an event which ran before this one could write more data to the
       // response body before we get around to canceling the copier. We have
       // tests for this in test_seizepower.js, however, and I can't think of a
       // way to handle both cases without removing bodyOutputStream access and
       // moving its effective write(data, length) method onto Response, which
       // would be slower and require more code than this anyway.
-      gThreadManager.currentThread.dispatch({
+      gThreadManager.dispatchToMainThread({
         run: function()
         {
           dumpn("*** canceling copy asynchronously...");
           copier.cancel(Cr.NS_ERROR_UNEXPECTED);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     }
     else
     {
       this.end();
     }
   },
 
   /**
@@ -4517,17 +4515,17 @@ WriteThroughCopier.prototype =
           {
             NS_ASSERT(false,
                       "how are we throwing an exception here? we control " +
                       "all the callers! " + e);
           }
         }
       };
 
-    gThreadManager.currentThread.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
+    gThreadManager.dispatchToMainThread(event);
   },
 
   /**
 * Kicks off another wait for more data to be available from the input stream.
 */
   _waitToReadData: function()
   {
     dumpn("*** _waitToReadData");
--- a/addon-sdk/source/test/lib/httpd.js
+++ b/addon-sdk/source/test/lib/httpd.js
@@ -452,18 +452,17 @@ nsHttpServer.prototype =
       var stopEvent =
         {
           run: function()
           {
             dumpn("*** _notifyStopped async callback");
             self._notifyStopped();
           }
         };
-      gThreadManager.currentThread
-                    .dispatch(stopEvent, Ci.nsIThread.DISPATCH_NORMAL);
+      gThreadManager.dispatchToMainThread(stopEvent);
     }
   },
 
   // NSIHTTPSERVER
 
   //
   // see nsIHttpServer.start
   //
@@ -2691,18 +2690,17 @@ ServerHandler.prototype =
       catch (e)
       {
         fis.close();
         throw e;
       }
 
       let writeMore = function writeMore()
       {
-        gThreadManager.currentThread
-                      .dispatch(writeData, Ci.nsIThread.DISPATCH_NORMAL);
+        gThreadManager.dispatchToMainThread(writeData);
       }
 
       var input = new BinaryInputStream(fis);
       var output = new BinaryOutputStream(response.bodyOutputStream);
       var writeData =
         {
           run: function()
           {
@@ -3763,23 +3761,23 @@ Response.prototype =
       // happening asynchronously with respect to the actual writing of data to
       // bodyOutputStream, as they currently do; if they happened synchronously,
       // an event which ran before this one could write more data to the
       // response body before we get around to canceling the copier. We have
       // tests for this in test_seizepower.js, however, and I can't think of a
       // way to handle both cases without removing bodyOutputStream access and
       // moving its effective write(data, length) method onto Response, which
       // would be slower and require more code than this anyway.
-      gThreadManager.currentThread.dispatch({
+      gThreadManager.dispatchToMainThread({
         run: function()
         {
           dumpn("*** canceling copy asynchronously...");
           copier.cancel(Cr.NS_ERROR_UNEXPECTED);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     }
     else
     {
       this.end();
     }
   },
 
   /**
@@ -4518,17 +4516,17 @@ WriteThroughCopier.prototype =
           {
             NS_ASSERT(false,
                       "how are we throwing an exception here? we control " +
                       "all the callers! " + e);
           }
         }
       };
 
-    gThreadManager.currentThread.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
+    gThreadManager.dispatchToMainThread(event);
   },
 
   /**
 * Kicks off another wait for more data to be available from the input stream.
 */
   _waitToReadData: function()
   {
     dumpn("*** _waitToReadData");
--- a/b2g/components/ErrorPage.jsm
+++ b/b2g/components/ErrorPage.jsm
@@ -45,19 +45,19 @@ SSLExceptions.prototype = {
   /**
    * To collect the SSL status we intercept the certificate error here
    * and store the status for later use.
    */
   notifyCertProblem: function SSLE_notifyCertProblem(aSocketInfo,
                                                      aSslStatus,
                                                      aTargetHost) {
     this._sslStatus = aSslStatus.QueryInterface(Ci.nsISSLStatus);
-    Services.tm.currentThread.dispatch({
+    Services.tm.dispatchToMainThread({
       run: this._addOverride.bind(this)
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
     return true; // suppress error UI
   },
 
   /**
    * Attempt to download the certificate for the location specified to get
    * the SSLState for the certificate and the errors.
    */
   _checkCert: function SSLE_checkCert() {
--- a/browser/base/content/browser-fullZoom.js
+++ b/browser/base/content/browser-fullZoom.js
@@ -516,11 +516,11 @@ var FullZoom = {
     this._executeSoon(function() {
       Services.obs.notifyObservers(browser, "browser-fullZoom:location-change");
     });
   },
 
   _executeSoon: function FullZoom__executeSoon(callback) {
     if (!callback)
       return;
-    Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(callback);
   },
 };
--- a/browser/base/content/test/tabPrompts/browser_multiplePrompts.js
+++ b/browser/base/content/test/tabPrompts/browser_multiplePrompts.js
@@ -55,17 +55,17 @@ add_task(function*() {
       }
 
       is(prompt.hidden, false, "The last prompt should not be hidden.");
       prompt.onButtonClick(0);
 
       // The click is handled async; wait for an event loop turn for that to
       // happen.
       yield new Promise(function(resolve) {
-        Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+        Services.tm.dispatchToMainThread(resolve);
       });
     }
   }
 
   let prompts = tab.linkedBrowser.parentNode.querySelectorAll("tabmodalprompt");
   is(prompts.length, 0, "Prompts should all be dismissed.");
 
   yield BrowserTestUtils.removeTab(tab);
--- a/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js
+++ b/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js
@@ -38,17 +38,17 @@ add_task(function*() {
   let checkbox = row.querySelector("checkbox[label*='example.com']");
   ok(checkbox, "The checkbox should be there");
   ok(!checkbox.checked, "Checkbox shouldn't be checked");
   // tick box and accept dialog
   checkbox.checked = true;
   ourPrompt.onButtonClick(0);
   // Wait for that click to actually be handled completely.
   yield new Promise(function(resolve) {
-    Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(resolve);
   });
   // check permission is set
   let ps = Services.perms;
   is(ps.ALLOW_ACTION, ps.testPermission(makeURI(pageWithAlert), "focus-tab-by-prompt"),
      "Tab switching should now be allowed");
 
   // Check if the control center shows the correct permission.
   let shown = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -2289,10 +2289,10 @@ function __dumpDragData(aEvent, caller) 
       str += "  dataTransfer[" + prop + "]: " + aEvent.dataTransfer[prop] + "\n";
     }
   }
   str += "}";
   log.debug(str);
 }
 
 function dispatchFunction(aFunc) {
-  Services.tm.currentThread.dispatch(aFunc, Ci.nsIThread.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread(aFunc);
 }
--- a/browser/components/downloads/content/allDownloadsViewOverlay.js
+++ b/browser/components/downloads/content/allDownloadsViewOverlay.js
@@ -1087,21 +1087,21 @@ DownloadsPlacesView.prototype = {
     if (this._richlistbox.selectedItem == this._initiallySelectedElement) {
       let firstDownloadElement = this._richlistbox.firstChild;
       if (firstDownloadElement != this._initiallySelectedElement) {
         // We may be called before _ensureVisibleElementsAreActive,
         // or before the download binding is attached. Therefore, ensure the
         // first item is activated, and pass the item to the richlistbox
         // setters only at a point we know for sure the binding is attached.
         firstDownloadElement._shell.ensureActive();
-        Services.tm.mainThread.dispatch(() => {
+        Services.tm.dispatchToMainThread(() => {
           this._richlistbox.selectedItem = firstDownloadElement;
           this._richlistbox.currentItem = firstDownloadElement;
           this._initiallySelectedElement = firstDownloadElement;
-        }, Ci.nsIThread.DISPATCH_NORMAL);
+        });
       }
     }
   },
 
   onDataLoadStarting() {},
   onDataLoadCompleted() {
     this._ensureInitialSelection();
   },
--- a/browser/components/extensions/ext-utils.js
+++ b/browser/components/extensions/ext-utils.js
@@ -388,19 +388,19 @@ class TabTracker extends TabTrackerBase 
     // addon-invoked calls are asynchronous since they go through a proxy
     // context via the message manager. This includes event registrations such
     // as `tabs.onRemoved.addListener`.
     //
     // So, even if `window.close()` were to be called (in-process) after calling
     // `tabs.onRemoved.addListener`, then the tab would be closed before the
     // event listener is registered. To make sure that the event listener is
     // notified, we dispatch `tabs.onRemoved` asynchronously.
-    Services.tm.mainThread.dispatch(() => {
+    Services.tm.dispatchToMainThread(() => {
       this.emit("tab-removed", {nativeTab, tabId, windowId, isWindowClosing});
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
   }
 
   getBrowserData(browser) {
     if (browser.ownerGlobal.location.href === "about:addons") {
       // When we're loaded into a <browser> inside about:addons, we need to go up
       // one more level.
       browser = browser.ownerGlobal.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIDocShell)
--- a/browser/components/migration/MigrationUtils.jsm
+++ b/browser/components/migration/MigrationUtils.jsm
@@ -230,17 +230,17 @@ this.MigratorPrototype = {
       throw new Error("migrate called for a non-existent source");
 
     if (aItems != Ci.nsIBrowserProfileMigrator.ALL)
       resources = resources.filter(r => aItems & r.type);
 
     // Used to periodically give back control to the main-thread loop.
     let unblockMainThread = function() {
       return new Promise(resolve => {
-        Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+        Services.tm.dispatchToMainThread(resolve);
       });
     };
 
     let getHistogramIdForResourceType = (resourceType, template) => {
       if (resourceType == MigrationUtils.resourceTypes.HISTORY) {
         return template.replace("*", "HISTORY");
       }
       if (resourceType == MigrationUtils.resourceTypes.BOOKMARKS) {
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1028,19 +1028,19 @@ BrowserGlue.prototype = {
                           .add(isDefaultError);
         Services.telemetry.getHistogramById("BROWSER_SET_DEFAULT_ALWAYS_CHECK")
                           .add(shouldCheck);
         Services.telemetry.getHistogramById("BROWSER_SET_DEFAULT_DIALOG_PROMPT_RAWCOUNT")
                           .add(promptCount);
       } catch (ex) { /* Don't break the default prompt if telemetry is broken. */ }
 
       if (willPrompt) {
-        Services.tm.mainThread.dispatch(function() {
+        Services.tm.dispatchToMainThread(function() {
           DefaultBrowserCheck.prompt(RecentWindow.getMostRecentBrowserWindow());
-        }, Ci.nsIThread.DISPATCH_NORMAL);
+        });
       }
     }
 
     E10SAccessibilityCheck.onWindowsRestored();
   },
 
   _createExtraDefaultProfile() {
     if (!AppConstants.MOZ_DEV_EDITION) {
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -1418,20 +1418,20 @@
               // actually what the user typed (e.g., it's autofilled, or it's a
               // mozaction URI), the consumer has some way of providing it.
               this.query = event.target.oneOffSearchQuery || event.target.value;
               break;
             case "popupshowing":
               this._rebuild();
               break;
             case "popuphidden":
-              Services.tm.mainThread.dispatch(() => {
+              Services.tm.dispatchToMainThread(() => {
                 this.selectedButton = null;
                 this._contextEngine = null;
-              }, Ci.nsIThread.DISPATCH_NORMAL);
+              });
               break;
           }
         ]]></body>
       </method>
 
       <method name="showSettings">
         <body><![CDATA[
           BrowserUITelemetry.countSearchSettingsEvent(this.telemetryOrigin);
--- a/browser/components/sessionstore/test/content.js
+++ b/browser/components/sessionstore/test/content.js
@@ -9,17 +9,17 @@
 var Cu = Components.utils;
 var Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/sessionstore/FrameTree.jsm", this);
 var gFrameTree = new FrameTree(this);
 
 function executeSoon(callback) {
-  Services.tm.mainThread.dispatch(callback, Components.interfaces.nsIThread.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread(callback);
 }
 
 gFrameTree.addObserver({
   onFrameTreeReset() {
     sendAsyncMessage("ss-test:onFrameTreeReset");
   },
 
   onFrameTreeCollected() {
--- a/browser/experiments/test/addons/experiment-racybranch/bootstrap.js
+++ b/browser/experiments/test/addons/experiment-racybranch/bootstrap.js
@@ -8,18 +8,17 @@ var gStarted = false;
 
 function startup(data, reasonCode) {
   if (gStarted) {
     return;
   }
   gStarted = true;
 
   // delay realstartup to trigger the race condition
-  Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager)
-    .mainThread.dispatch(realstartup, 0);
+  Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager).dispatchToMainThread(realstartup);
 }
 
 function realstartup() {
   let experiments = Experiments.instance();
   let experiment = experiments._getActiveExperiment();
   if (experiment.branch) {
     Cu.reportError("Found pre-existing branch: " + experiment.branch);
     return;
--- a/browser/modules/SocialService.jsm
+++ b/browser/modules/SocialService.jsm
@@ -325,17 +325,17 @@ function initService() {
     // no matter what, if migration fails we do not want to render social
     // unusable. Worst case scenario is that, when upgrading Firefox, previously
     // enabled providers are not migrated.
     Cu.reportError("Error migrating social settings: " + e);
   }
 }
 
 function schedule(callback) {
-  Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread(callback);
 }
 
 // Public API
 this.SocialService = {
   get hasEnabledProviders() {
     // used as an optimization during startup, can be used to check if further
     // initialization should be done (e.g. creating the instances of
     // SocialProvider and turning on UI). ActiveProviders may have changed and
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -169,19 +169,19 @@ this.webrtcUI = {
       browserWindow.gBrowser.selectedTab = aActiveStream.tab;
     } else {
       aActiveStream.browser.focus();
     }
     browserWindow.focus();
     let identityBox = browserWindow.document.getElementById("identity-box");
     if (AppConstants.platform == "macosx" && !Services.focus.activeWindow) {
       browserWindow.addEventListener("activate", function() {
-        Services.tm.mainThread.dispatch(function() {
+        Services.tm.dispatchToMainThread(function() {
           identityBox.click();
-        }, Ci.nsIThread.DISPATCH_NORMAL);
+        });
       }, {once: true});
       Cc["@mozilla.org/widget/macdocksupport;1"].getService(Ci.nsIMacDockSupport)
         .activateApplication(true);
       return;
     }
     identityBox.click();
   },
 
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -9205,23 +9205,23 @@ return /******/ (function(modules) { // 
 	}
 	StreamCopier._nextId = 0;
 
 	StreamCopier.prototype = {
 
 	  copy: function() {
 	    // Dispatch to the next tick so that it's possible to attach a progress
 	    // event listener, even for extremely fast copies (like when testing).
-	    Services.tm.currentThread.dispatch(() => {
+	    Services.tm.dispatchToMainThread(() => {
 	      try {
 	        this._copy();
 	      } catch (e) {
 	        this._deferred.reject(e);
 	      }
-	    }, 0);
+	    });
 	    return this;
 	  },
 
 	  _copy: function() {
 	    let bytesAvailable = this.input.available();
 	    let amountToCopy = Math.min(bytesAvailable, this._amountLeft);
 	    this._debug("Trying to copy: " + amountToCopy);
 
--- a/devtools/client/debugger/new/integration-tests.js
+++ b/devtools/client/debugger/new/integration-tests.js
@@ -8043,23 +8043,23 @@ return /******/ (function(modules) { // 
 	}
 	StreamCopier._nextId = 0;
 	
 	StreamCopier.prototype = {
 	
 	  copy: function() {
 	    // Dispatch to the next tick so that it's possible to attach a progress
 	    // event listener, even for extremely fast copies (like when testing).
-	    Services.tm.currentThread.dispatch(() => {
+	    Services.tm.dispatchToMainThread(() => {
 	      try {
 	        this._copy();
 	      } catch (e) {
 	        this._deferred.reject(e);
 	      }
-	    }, 0);
+	    });
 	    return this;
 	  },
 	
 	  _copy: function() {
 	    let bytesAvailable = this.input.available();
 	    let amountToCopy = Math.min(bytesAvailable, this._amountLeft);
 	    this._debug("Trying to copy: " + amountToCopy);
 	
--- a/devtools/client/debugger/views/global-search-view.js
+++ b/devtools/client/debugger/views/global-search-view.js
@@ -230,19 +230,19 @@ GlobalSearchView.prototype = Heritage.ex
 
     for (let sourceResults of aGlobalResults) {
       if (i++ == 0) {
         this._createSourceResultsUI(sourceResults);
       } else {
         // Dispatch subsequent document manipulation operations, to avoid
         // blocking the main thread when a large number of search results
         // is found, thus giving the impression of faster searching.
-        Services.tm.currentThread.dispatch({ run:
+        Services.tm.dispatchToMainThread({ run:
           this._createSourceResultsUI.bind(this, sourceResults)
-        }, 0);
+        });
       }
     }
   },
 
   /**
    * Creates source search results entries and adds them to this container.
    *
    * @param SourceResults aSourceResults
@@ -327,22 +327,22 @@ GlobalSearchView.prototype = Heritage.ex
 
   /**
    * Starts a bounce animation for a match.
    *
    * @param nsIDOMNode aMatch
    *        The match to start a bounce animation for.
    */
   _bounceMatch: function (aMatch) {
-    Services.tm.currentThread.dispatch({ run: () => {
+    Services.tm.dispatchToMainThread({ run: () => {
       aMatch.addEventListener("transitionend", function () {
         aMatch.removeAttribute("focused");
       }, {once: true});
       aMatch.setAttribute("focused", "");
-    }}, 0);
+    }});
     aMatch.setAttribute("focusing", "");
   },
 
   _splitter: null,
   _currentlyFocusedMatch: -1,
   _forceExpandResults: false
 });
 
--- a/devtools/client/shared/DOMHelpers.jsm
+++ b/devtools/client/shared/DOMHelpers.jsm
@@ -147,20 +147,20 @@ DOMHelpers.prototype = {
                          .getInterface(Ci.nsIWebNavigation)
                          .QueryInterface(Ci.nsIDocShell);
     let onReady = function (event) {
       if (event.target == window.document) {
         docShell.chromeEventHandler.removeEventListener("DOMContentLoaded", onReady);
         // If in `callback` the URL of the window is changed and a listener to DOMContentLoaded
         // is attached, the event we just received will be also be caught by the new listener.
         // We want to avoid that so we execute the callback in the next queue.
-        Services.tm.mainThread.dispatch(callback, 0);
+        Services.tm.dispatchToMainThread(callback);
       }
     };
     if ((window.document.readyState == "complete" ||
          window.document.readyState == "interactive") &&
          window.location.href == targetURL) {
-      Services.tm.mainThread.dispatch(callback, 0);
+      Services.tm.dispatchToMainThread(callback);
     } else {
       docShell.chromeEventHandler.addEventListener("DOMContentLoaded", onReady);
     }
   }
 };
--- a/devtools/client/shared/widgets/VariablesView.jsm
+++ b/devtools/client/shared/widgets/VariablesView.jsm
@@ -1492,17 +1492,17 @@ Scope.prototype = {
   expand: function () {
     if (this._isExpanded || this._isLocked) {
       return;
     }
     if (this._variablesView._enumVisible) {
       this._openEnum();
     }
     if (this._variablesView._nonEnumVisible) {
-      Services.tm.currentThread.dispatch({ run: this._openNonEnum }, 0);
+      Services.tm.dispatchToMainThread({ run: this._openNonEnum });
     }
     this._isExpanded = true;
 
     if (this.onexpand) {
       // We return onexpand as it sometimes returns a promise
       // (up to the user of VariableView to do it)
       // that can indicate when the view is done expanding
       // and attributes are available. (Mostly used for tests)
--- a/devtools/server/actors/tab.js
+++ b/devtools/server/actors/tab.js
@@ -952,38 +952,38 @@ TabActor.prototype = {
 
   /**
    * Reload the page in this tab.
    */
   onReload(request) {
     let force = request && request.options && request.options.force;
     // Wait a tick so that the response packet can be dispatched before the
     // subsequent navigation event packet.
-    Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(() => {
+    Services.tm.dispatchToMainThread(DevToolsUtils.makeInfallible(() => {
       // This won't work while the browser is shutting down and we don't really
       // care.
       if (Services.startup.shuttingDown) {
         return;
       }
       this.webNavigation.reload(force ?
         Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE :
         Ci.nsIWebNavigation.LOAD_FLAGS_NONE);
-    }, "TabActor.prototype.onReload's delayed body"), 0);
+    }, "TabActor.prototype.onReload's delayed body"));
     return {};
   },
 
   /**
    * Navigate this tab to a new location
    */
   onNavigateTo(request) {
     // Wait a tick so that the response packet can be dispatched before the
     // subsequent navigation event packet.
-    Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(() => {
+    Services.tm.dispatchToMainThread(DevToolsUtils.makeInfallible(() => {
       this.window.location = request.url;
-    }, "TabActor.prototype.onNavigateTo's delayed body"), 0);
+    }, "TabActor.prototype.onNavigateTo's delayed body"));
     return {};
   },
 
   /**
    * Reconfigure options.
    */
   onReconfigure(request) {
     let options = request.options || {};
--- a/devtools/server/actors/webbrowser.js
+++ b/devtools/server/actors/webbrowser.js
@@ -666,28 +666,28 @@ DevToolsUtils.makeInfallible(function (w
     return;
   }
 
   /*
    * nsIWindowMediator deadlocks if you call its GetEnumerator method from
    * a nsIWindowMediatorListener's onCloseWindow hook (bug 873589), so
    * handle the close in a different tick.
    */
-  Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(() => {
+  Services.tm.dispatchToMainThread(DevToolsUtils.makeInfallible(() => {
     /*
      * Scan the entire map for actors representing tabs that were in this
      * top-level window, and exit them.
      */
     for (let [browser, actor] of this._actorByBrowser) {
       /* The browser document of a closed window has no default view. */
       if (!browser.ownerGlobal) {
         this._handleActorClose(actor, browser);
       }
     }
-  }, "BrowserTabList.prototype.onCloseWindow's delayed body"), 0);
+  }, "BrowserTabList.prototype.onCloseWindow's delayed body"));
 }, "BrowserTabList.prototype.onCloseWindow");
 
 exports.BrowserTabList = BrowserTabList;
 
 /**
  * Creates a tab actor for handling requests to a single browser frame.
  * Both <xul:browser> and <iframe mozbrowser> are supported.
  * This actor is a shim that connects to a ContentActor in a remote browser process.
--- a/devtools/server/actors/webextension-inspected-window.js
+++ b/devtools/server/actors/webextension-inspected-window.js
@@ -310,17 +310,17 @@ var WebExtensionInspectedWindowActor = p
           }
           this.webNavigation.reload(reloadFlags);
         }
       };
 
       // Execute the reload in a dispatched runnable, so that we can
       // return the reply to the caller before the reload is actually
       // started.
-      Services.tm.currentThread.dispatch(delayedReload, 0);
+      Services.tm.dispatchToMainThread(delayedReload);
 
       return {};
     },
 
     /**
      * Evaluate the provided javascript code in a target window (that is always the
      * tabActor window when called through RDP protocol, or the passed customTargetWindow
      * when called directly from the CustomizedReload instances).
--- a/devtools/server/tests/unit/head_dbg.js
+++ b/devtools/server/tests/unit/head_dbg.js
@@ -580,19 +580,19 @@ TracingTransport.prototype = {
 };
 
 function StubTransport() { }
 StubTransport.prototype.ready = function () {};
 StubTransport.prototype.send = function () {};
 StubTransport.prototype.close = function () {};
 
 function executeSoon(func) {
-  Services.tm.mainThread.dispatch({
+  Services.tm.dispatchToMainThread({
     run: DevToolsUtils.makeInfallible(func)
-  }, Ci.nsIThread.DISPATCH_NORMAL);
+  });
 }
 
 // The do_check_* family of functions expect their last argument to be an
 // optional stack object. Unfortunately, most tests actually pass a in a string
 // containing an error message instead, which causes error reporting to break if
 // strict warnings as errors is turned on. To avoid this, we wrap these
 // functions here below to ensure the correct number of arguments is passed.
 //
--- a/devtools/server/tests/unit/test_blackboxing-05.js
+++ b/devtools/server/tests/unit/test_blackboxing-05.js
@@ -19,19 +19,19 @@ function run_test() {
   gClient.connect().then(function () {
     attachTestTabAndResume(
       gClient, "test-black-box",
       function (response, tabClient, threadClient) {
         gThreadClient = threadClient;
         // XXX: We have to do an executeSoon so that the error isn't caught and
         // reported by DebuggerClient.requester (because we are using the local
         // transport and share a stack) which causes the test to fail.
-        Services.tm.mainThread.dispatch({
+        Services.tm.dispatchToMainThread({
           run: test_black_box
-        }, Ci.nsIThread.DISPATCH_NORMAL);
+        });
       });
   });
   do_test_pending();
 }
 
 const BLACK_BOXED_URL = "http://example.com/blackboxme.js";
 const SOURCE_URL = "http://example.com/source.js";
 
--- a/devtools/server/tests/unit/test_nsjsinspector.js
+++ b/devtools/server/tests/unit/test_nsjsinspector.js
@@ -17,43 +17,43 @@ var requestor = (count) => ({
 
 function run_test() {
   test_nesting();
 }
 
 function test_nesting() {
   do_check_eq(inspector.eventLoopNestLevel, 0);
 
-  tm.currentThread.dispatch({ run: enterEventLoop}, 0);
+  tm.dispatchToMainThread({ run: enterEventLoop});
 
   do_check_eq(inspector.enterNestedEventLoop(requestor(gCount)), 0);
   do_check_eq(inspector.eventLoopNestLevel, 0);
   do_check_eq(inspector.lastNestRequestor, null);
 }
 
 function enterEventLoop() {
   if (gCount++ < MAX) {
-    tm.currentThread.dispatch({ run: enterEventLoop}, 0);
+    tm.dispatchToMainThread({ run: enterEventLoop});
 
     Object.create(requestor(gCount));
 
     do_check_eq(inspector.eventLoopNestLevel, gCount);
     do_check_eq(inspector.lastNestRequestor.url, requestor(gCount - 1).url);
     do_check_eq(inspector.lastNestRequestor.connection, requestor(gCount - 1).connection);
     do_check_eq(inspector.enterNestedEventLoop(requestor(gCount)), gCount);
   } else {
     do_check_eq(gCount, MAX + 1);
-    tm.currentThread.dispatch({ run: exitEventLoop}, 0);
+    tm.dispatchToMainThread({ run: exitEventLoop});
   }
 }
 
 function exitEventLoop() {
   if (inspector.lastNestRequestor != null) {
     do_check_eq(inspector.lastNestRequestor.url, requestor(gCount - 1).url);
     do_check_eq(inspector.lastNestRequestor.connection, requestor(gCount - 1).connection);
     if (gCount-- > 1) {
-      tm.currentThread.dispatch({ run: exitEventLoop}, 0);
+      tm.dispatchToMainThread({ run: exitEventLoop});
     }
 
     do_check_eq(inspector.exitNestedEventLoop(), gCount);
     do_check_eq(inspector.eventLoopNestLevel, gCount);
   }
 }
--- a/devtools/server/tests/unit/test_stepping-06.js
+++ b/devtools/server/tests/unit/test_stepping-06.js
@@ -28,19 +28,19 @@ function run_test_with_server(server, ca
   gClient.connect().then(function () {
     attachTestTabAndResume(
       gClient, "test-stack",
       function (response, tabClient, threadClient) {
         gThreadClient = threadClient;
         // XXX: We have to do an executeSoon so that the error isn't caught and
         // reported by DebuggerClient.requester (because we are using the local
         // transport and share a stack) which causes the test to fail.
-        Services.tm.mainThread.dispatch({
+        Services.tm.dispatchToMainThread({
           run: test_simple_stepping
-        }, Ci.nsIThread.DISPATCH_NORMAL);
+        });
       });
   });
 }
 
 function test_simple_stepping() {
   gThreadClient.addOneTimeListener("paused", function (event, packet) {
     gThreadClient.addOneTimeListener("paused", function (event, packet) {
       // Check that the return value is 10.
--- a/devtools/shared/DevToolsUtils.js
+++ b/devtools/shared/DevToolsUtils.js
@@ -41,19 +41,19 @@ exports.executeSoon = function (fn) {
     if (AppConstants.DEBUG_JS_MODULES || flags.testing) {
       let stack = getStack();
       executor = () => {
         callFunctionWithAsyncStack(fn, stack, "DevToolsUtils.executeSoon");
       };
     } else {
       executor = fn;
     }
-    Services.tm.mainThread.dispatch({
+    Services.tm.dispatchToMainThread({
       run: exports.makeInfallible(executor)
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
   }
 };
 
 /**
  * Waits for the next tick in the event loop.
  *
  * @return Promise
  *         A promise that is resolved after the next tick in the event loop.
--- a/devtools/shared/transport/stream-utils.js
+++ b/devtools/shared/transport/stream-utils.js
@@ -94,23 +94,23 @@ function StreamCopier(input, output, len
 }
 StreamCopier._nextId = 0;
 
 StreamCopier.prototype = {
 
   copy: function () {
     // Dispatch to the next tick so that it's possible to attach a progress
     // event listener, even for extremely fast copies (like when testing).
-    Services.tm.currentThread.dispatch(() => {
+    Services.tm.dispatchToMainThread(() => {
       try {
         this._copy();
       } catch (e) {
         this._deferred.reject(e);
       }
-    }, 0);
+    });
     return this;
   },
 
   _copy: function () {
     let bytesAvailable = this.input.available();
     let amountToCopy = Math.min(bytesAvailable, this._amountLeft);
     this._debug("Trying to copy: " + amountToCopy);
 
--- a/dom/base/IndexedDBHelper.jsm
+++ b/dom/base/IndexedDBHelper.jsm
@@ -66,18 +66,17 @@ IndexedDBHelper.prototype = {
     };
 
     if (DEBUG) debug("Try to open database:" + self.dbName + " " + self.dbVersion);
     let req;
     try {
       req = indexedDB.open(this.dbName, this.dbVersion);
     } catch (e) {
       if (DEBUG) debug("Error opening database: " + self.dbName);
-      Services.tm.currentThread.dispatch(() => invokeCallbacks(getErrorName(e)),
-                                         Ci.nsIThread.DISPATCH_NORMAL);
+      Services.tm.dispatchToMainThread(() => invokeCallbacks(getErrorName(e)));
       return;
     }
     req.onsuccess = function (event) {
       if (DEBUG) debug("Opened database:" + self.dbName + " " + self.dbVersion);
       self._db = event.target.result;
       self._db.onversionchange = function(event) {
         if (DEBUG) debug("WARNING: DB modified from a different window.");
       }
@@ -109,18 +108,17 @@ IndexedDBHelper.prototype = {
    *        Success callback to call.
    * @param failureCb
    *        Error callback to call when an error is encountered.
    */
   ensureDB: function ensureDB(aSuccessCb, aFailureCb) {
     if (this._db) {
       if (DEBUG) debug("ensureDB: already have a database, returning early.");
       if (aSuccessCb) {
-        Services.tm.currentThread.dispatch(aSuccessCb,
-                                           Ci.nsIThread.DISPATCH_NORMAL);
+        Services.tm.dispatchToMainThread(aSuccessCb);
       }
       return;
     }
     this.open(aError => {
       if (aError) {
         aFailureCb && aFailureCb(aError);
       } else {
         aSuccessCb && aSuccessCb();
--- a/dom/base/test/file_simplecontentpolicy.js
+++ b/dom/base/test/file_simplecontentpolicy.js
@@ -2,17 +2,17 @@ var Ci = Components.interfaces;
 var Cc = Components.classes;
 var Cr = Components.results;
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 function executeSoon(f)
 {
-  Services.tm.mainThread.dispatch(f, Ci.nsIThread.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread(f);
 }
 
 var urlSuffix = "/this/is/the/test/url";
 
 // Content policy / factory implementation for the test
 var policyID = Components.ID("{6aadacff-f1f2-46f4-a6db-6d429f884a30}");
 var policyName = "@mozilla.org/simpletestpolicy;1";
 var policy = {
--- a/dom/browser-element/BrowserElementPromptService.jsm
+++ b/dom/browser-element/BrowserElementPromptService.jsm
@@ -364,17 +364,17 @@ BrowserElementAuthPrompt.prototype = {
       run: function() {
         // Call promptAuth of browserElementParent, to show the prompt.
         prompt.browserElementParent.promptAuth(
           self._createAuthDetail(prompt.channel, prompt.authInfo),
           callback);
       }
     }
 
-    Services.tm.currentThread.dispatch(runnable, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(runnable);
   },
 
   _getFrameFromChannel: function(channel) {
     let loadContext = channel.notificationCallbacks.getInterface(Ci.nsILoadContext);
     return loadContext.topFrameElement;
   },
 
   _createAuthDetail: function(channel, authInfo) {
--- a/dom/notification/NotificationStorage.js
+++ b/dom/notification/NotificationStorage.js
@@ -219,36 +219,34 @@ NotificationStorage.prototype = {
       }
     }
 
     // Pass each notification back separately.
     // The callback is called asynchronously to match the behaviour when
     // fetching from the database.
     notifications.forEach(function(notification) {
       try {
-        Services.tm.currentThread.dispatch(
+        Services.tm.dispatchToMainThread(
           callback.handle.bind(callback,
                                notification.id,
                                notification.title,
                                notification.dir,
                                notification.lang,
                                notification.body,
                                notification.tag,
                                notification.icon,
                                notification.data,
                                notification.mozbehavior,
-                               notification.serviceWorkerRegistrationScope),
-          Ci.nsIThread.DISPATCH_NORMAL);
+                               notification.serviceWorkerRegistrationScope));
       } catch (e) {
         if (DEBUG) { debug("Error calling callback handle: " + e); }
       }
     });
     try {
-      Services.tm.currentThread.dispatch(callback.done,
-                                         Ci.nsIThread.DISPATCH_NORMAL);
+      Services.tm.dispatchToMainThread(callback.done);
     } catch (e) {
       if (DEBUG) { debug("Error calling callback done: " + e); }
     }
   },
 
   _populateCache: function(notifications) {
     notifications.forEach(function(notification) {
       this._notifications[notification.id] = notification;
--- a/dom/presentation/provider/PresentationControlService.js
+++ b/dom/presentation/provider/PresentationControlService.js
@@ -119,29 +119,29 @@ PresentationControlService.prototype = {
 
     // Monitor network interface change to restart server socket.
     Services.obs.addObserver(this, "network:offline-status-changed");
 
     this._notifyServerReady();
   },
 
   _notifyServerReady: function() {
-    Services.tm.mainThread.dispatch(() => {
+    Services.tm.dispatchToMainThread(() => {
       if (this._listener) {
         this._listener.onServerReady(this._port, this.certFingerprint);
       }
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
   },
 
   _notifyServerStopped: function(aRv) {
-    Services.tm.mainThread.dispatch(() => {
+    Services.tm.dispatchToMainThread(() => {
       if (this._listener) {
         this._listener.onServerStopped(aRv);
       }
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
   },
 
   isCompatibleServer: function(aVersion) {
     // No compatibility issue for the first version of control protocol
     return this.version === aVersion;
   },
 
   get id() {
--- a/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js
+++ b/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js
@@ -44,19 +44,19 @@ const mockControlChannelOfSender = {
   },
   notifyReconnected: function() {
     // send offer after notifyOpened immediately
     this._listener
         .QueryInterface(Ci.nsIPresentationControlChannelListener)
         .notifyReconnected();
   },
   sendOffer: function(offer) {
-    Services.tm.mainThread.dispatch(() => {
+    Services.tm.dispatchToMainThread(() => {
       mockControlChannelOfReceiver.onOffer(offer);
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
   },
   onAnswer: function(answer) {
     this._listener
         .QueryInterface(Ci.nsIPresentationControlChannelListener)
         .onAnswer(answer);
   },
   launch: function(presentationId, url) {
     sessionId = presentationId;
@@ -122,19 +122,19 @@ const mockControlChannelOfReceiver = {
         .notifyConnected();
   },
   onOffer: function(offer) {
     this._listener
         .QueryInterface(Ci.nsIPresentationControlChannelListener)
         .onOffer(offer);
   },
   sendAnswer: function(answer) {
-    Services.tm.mainThread.dispatch(() => {
+    Services.tm.dispatchToMainThread(() => {
       mockControlChannelOfSender.onAnswer(answer);
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
   },
   disconnect: function(reason) {
     if (!this._listener) {
       return;
     }
 
     this._listener
         .QueryInterface(Ci.nsIPresentationControlChannelListener)
--- a/dom/presentation/tests/xpcshell/test_multicast_dns_device_provider.js
+++ b/dom/presentation/tests/xpcshell/test_multicast_dns_device_provider.js
@@ -799,19 +799,19 @@ function ignoreIncompatibleDevice() {
                                               mockDevice.serviceName,
                                               mockDevice.serviceType));
     }
   };
 
   let mockServerObj = {
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlService]),
     startServer: function() {
-      Services.tm.currentThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         this.listener.onServerReady(this.port, this.certFingerprint);
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     },
     sessionRequest: function() {},
     close: function() {},
     id: '',
     version: LATEST_VERSION,
     isCompatibleServer: function(version) {
       return false;
     },
@@ -884,19 +884,19 @@ function ignoreSelfDevice() {
                                               mockDevice.serviceName,
                                               mockDevice.serviceType));
     }
   };
 
   let mockServerObj = {
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlService]),
     startServer: function() {
-      Services.tm.currentThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         this.listener.onServerReady(this.port, this.certFingerprint);
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     },
     sessionRequest: function() {},
     close: function() {},
     id: '',
     version: LATEST_VERSION,
     isCompatibleServer: function(version) {
       return this.version === version;
     },
@@ -1248,24 +1248,24 @@ function serverRetry() {
     resolveService: function(serviceInfo, listener) {}
   };
 
   let mockServerObj = {
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlService]),
     startServer: function(encrypted, port) {
       if (!isRetrying) {
         isRetrying = true;
-        Services.tm.currentThread.dispatch(() => {
+        Services.tm.dispatchToMainThread(() => {
           this.listener.onServerStopped(Cr.NS_ERROR_FAILURE);
-        }, Ci.nsIThread.DISPATCH_NORMAL);
+        });
       } else {
         this.port = 54321;
-        Services.tm.currentThread.dispatch(() => {
+        Services.tm.dispatchToMainThread(() => {
           this.listener.onServerReady(this.port, this.certFingerprint);
-        }, Ci.nsIThread.DISPATCH_NORMAL);
+        });
       }
     },
     sessionRequest: function() {},
     close: function() {},
     id: '',
     version: LATEST_VERSION,
     port: 0,
     certFingerprint: 'mock-cert-fingerprint',
--- a/dom/system/gonk/DataCallManager.js
+++ b/dom/system/gonk/DataCallManager.js
@@ -1295,23 +1295,23 @@ DataCall.prototype = {
 
     if (this.state == NETWORK_STATE_CONNECTING ||
         this.state == NETWORK_STATE_DISCONNECTING) {
       return;
     }
     if (this.state == NETWORK_STATE_CONNECTED) {
       // This needs to run asynchronously, to behave the same way as the case of
       // non-shared apn, see bug 1059110.
-      Services.tm.currentThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         // Do not notify if state changed while this event was being dispatched,
         // the state probably was notified already or need not to be notified.
         if (aNetworkInterface.info.state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
           aNetworkInterface.notifyRILNetworkInterface();
         }
-      }, Ci.nsIEventTarget.DISPATCH_NORMAL);
+      });
       return;
     }
 
     // If retry mechanism is running on background, stop it since we are going
     // to setup data call now.
     if (this.timer) {
       this.timer.cancel();
     }
@@ -1426,28 +1426,28 @@ DataCall.prototype = {
         }
         this.reset();
         return;
       }
 
       // Notify the DISCONNECTED event immediately after network interface is
       // removed from requestedNetworkIfaces, to make the DataCall, shared or
       // not, to have the same behavior.
-      Services.tm.currentThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         // Do not notify if state changed while this event was being dispatched,
         // the state probably was notified already or need not to be notified.
         if (aNetworkInterface.info.state == RIL.GECKO_NETWORK_STATE_DISCONNECTED) {
           aNetworkInterface.notifyRILNetworkInterface();
 
           // Clear link info after notifying NetworkManager.
           if (this.requestedNetworkIfaces.length === 0) {
             this.resetLinkInfo();
           }
         }
-      }, Ci.nsIEventTarget.DISPATCH_NORMAL);
+      });
     }
 
     // Only deactivate data call if no more network interface needs this
     // DataCall and if state is CONNECTED, for other states, we simply remove
     // the network interface from requestedNetworkIfaces.
     if (this.requestedNetworkIfaces.length > 0 ||
         this.state != NETWORK_STATE_CONNECTED) {
       return;
--- a/dom/system/gonk/NetworkService.js
+++ b/dom/system/gonk/NetworkService.js
@@ -110,19 +110,19 @@ NetworkWorkerRequestQueue.prototype = {
     if (!this.tasks.length || this.tasks[0].id != aId) {
       debug("Id " + aId + " is not on top of the queue");
       return;
     }
 
     this.tasks.shift();
     if (this.tasks.length > 0) {
       // Run queue on the next tick.
-      Services.tm.currentThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         this.runQueue();
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     }
   }
 };
 
 
 /**
  * This component watches for network interfaces changing state and then
  * adjusts routes etc. accordingly.
--- a/dom/system/gonk/TetheringService.js
+++ b/dom/system/gonk/TetheringService.js
@@ -588,19 +588,19 @@ TetheringService.prototype = {
       // Disable wifi tethering with a useful error message for the user.
       settingsLock.set("tethering.wifi.enabled", false, null, aMsg);
     }
 
     debug("setWifiTethering: " + (aMsg ? aMsg : "success"));
 
     if (aCallback) {
       // Callback asynchronously to avoid netsted toggling.
-      Services.tm.currentThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         aCallback.wifiTetheringEnabledChange(aMsg);
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     }
   },
 
   enableWifiTethering: function(aEnable, aConfig, aCallback) {
     // Fill in config's required fields.
     aConfig.ifname         = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
     aConfig.internalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
     aConfig.externalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface;
--- a/js/xpconnect/tests/unit/head_ongc.js
+++ b/js/xpconnect/tests/unit/head_ongc.js
@@ -21,18 +21,17 @@ function newGlobal() {
   const global = new Cu.Sandbox(systemPrincipal, { freshZone: true });
   addTestingFunctionsToGlobal(global);
   return global;
 }
 
 addTestingFunctionsToGlobal(this);
 
 function executeSoon(f) {
-  Services.tm.mainThread.dispatch({ run: f },
-                                  Ci.nsIThread.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread({ run: f });
 }
 
 // The onGarbageCollection tests don't play well gczeal settings and lead to
 // intermittents.
 if (typeof gczeal == "function") {
   gczeal(0);
 }
 
--- a/js/xpconnect/tests/unit/head_watchdog.js
+++ b/js/xpconnect/tests/unit/head_watchdog.js
@@ -51,17 +51,17 @@ function do_log_info(aMessage)
   print("TEST-INFO | " + _TEST_FILE + " | " + aMessage);
 }
 
 // We don't use do_execute_soon, because that inserts a
 // do_test_{pending,finished} pair that gets screwed up when we terminate scripts
 // from the operation callback.
 function executeSoon(fn) {
   var tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
-  tm.mainThread.dispatch({run: fn}, Ci.nsIThread.DISPATCH_NORMAL);
+  tm.dispatchToMainThread({run: fn});
 }
 
 //
 // Asynchronous watchdog diagnostics.
 //
 // When running, the watchdog wakes up every second, and fires the operation
 // callback if the script has been running for >= the minimum script timeout.
 // As such, if the script timeout is 1 second, a script should never be able to
--- a/mobile/android/components/PromptService.js
+++ b/mobile/android/components/PromptService.js
@@ -486,17 +486,17 @@ InternalPrompt.prototype = {
             else
               consumer.callback.onAuthCancelled(consumer.context, true);
           } catch (e) { /* Throw away exceptions caused by callback */ }
         }
         self._doAsyncPrompt();
       }
     }
 
-    Services.tm.mainThread.dispatch(runnable, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(runnable);
   },
 
   asyncPromptAuth: function asyncPromptAuth(aChannel, aCallback, aContext, aLevel, aAuthInfo) {
     let cancelable = null;
     try {
       // If the user submits a login but it fails, we need to remove the
       // notification bar that was displayed. Conveniently, the user will
       // be prompted for authentication again, which brings us here.
--- a/mobile/android/components/extensions/ext-utils.js
+++ b/mobile/android/components/extensions/ext-utils.js
@@ -322,19 +322,19 @@ class TabTracker extends TabTrackerBase 
    *        True if the tab is being removed because the browser window is
    *        closing.
    * @private
    */
   emitRemoved(nativeTab, isWindowClosing) {
     let windowId = windowTracker.getId(nativeTab.browser.ownerGlobal);
     let tabId = this.getId(nativeTab);
 
-    Services.tm.mainThread.dispatch(() => {
+    Services.tm.dispatchToMainThread(() => {
       this.emit("tab-removed", {nativeTab, tabId, windowId, isWindowClosing});
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
   }
 
   getBrowserData(browser) {
     let result = {
       tabId: -1,
       windowId: -1,
     };
 
--- a/mobile/android/modules/MediaPlayerApp.jsm
+++ b/mobile/android/modules/MediaPlayerApp.jsm
@@ -63,19 +63,19 @@ MediaPlayerApp.prototype = {
 
 /* RemoteMedia provides a proxy to a native media player session.
  */
 function RemoteMedia(id, listener) {
   this._id = id;
   this._listener = listener;
 
   if ("onRemoteMediaStart" in this._listener) {
-    Services.tm.mainThread.dispatch((function() {
+    Services.tm.dispatchToMainThread((function() {
       this._listener.onRemoteMediaStart(this);
-    }).bind(this), Ci.nsIThread.DISPATCH_NORMAL);
+    }).bind(this));
   }
 }
 
 RemoteMedia.prototype = {
   shutdown: function shutdown() {
     EventDispatcher.instance.unregisterListener(this, [
       "MediaPlayer:Playing",
       "MediaPlayer:Paused",
--- a/mobile/android/tests/browser/chrome/test_awsy_lite.html
+++ b/mobile/android/tests/browser/chrome/test_awsy_lite.html
@@ -63,17 +63,17 @@
     }
   };
 
   function doFullGc(aCallback, aIterations) {
     var threadMan = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
     var domWindowUtils = gWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils);
 
     function runSoon(f) {
-        threadMan.mainThread.dispatch({ run: f }, Ci.nsIThread.DISPATCH_NORMAL);
+        threadMan.dispatchToMainThread({ run: f });
     }
 
     function cc() {
         if (domWindowUtils.cycleCollect) {
             domWindowUtils.cycleCollect();
         }
         Services.obs.notifyObservers(null, "child-cc-request");
     }
--- a/mobile/android/tests/browser/chrome/test_video_discovery.html
+++ b/mobile/android/tests/browser/chrome/test_video_discovery.html
@@ -65,17 +65,17 @@ Migrated from Robocop: https://bugzilla.
 
     // Poke the service directly to get the discovery to happen
     SimpleServiceDiscovery._processService(service);
 
     // Load our test web page with <video> elements
     let url = "http://mochi.test:8888/chrome/mobile/android/tests/browser/chrome/video_discovery.html";
     browser = BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
     browser.addEventListener("load", function(event) {
-      Services.tm.mainThread.dispatch(test_video, Ci.nsIThread.DISPATCH_NORMAL);
+      Services.tm.dispatchToMainThread(test_video);
     }, {capture: true, once: true});
   }
 
   let videoDiscoveryTests = [
     { id: "simple-mp4", source: "http://mochi.test:8888/simple.mp4", poster: "http://mochi.test:8888/simple.png", text: "simple video with mp4 src" },
     { id: "simple-fail", pass: false, text: "simple video with no mp4 src" },
     { id: "with-sources-mp4", source: "http://mochi.test:8888/simple.mp4", text: "video with mp4 extension source child" },
     { id: "with-sources-webm", source: "http://mochi.test:8888/simple.webm", text: "video with webm extension source child" },
--- a/mobile/android/tests/browser/robocop/robocop_head.js
+++ b/mobile/android/tests/browser/robocop/robocop_head.js
@@ -194,17 +194,17 @@ function do_timeout(delay, func) {
   new _Timer(func, Number(delay));
 }
 
 function do_execute_soon(callback) {
   do_test_pending();
   var tm = Components.classes["@mozilla.org/thread-manager;1"]
                      .getService(Components.interfaces.nsIThreadManager);
 
-  tm.mainThread.dispatch({
+  tm.dispatchToMainThread({
     run: function() {
       try {
         callback();
       } catch (e) {
         // do_check failures are already logged and set _quit to true and throw
         // NS_ERROR_ABORT. If both of those are true it is likely this exception
         // has already been logged so there is no need to log it again. It's
         // possible that this will mask an NS_ERROR_ABORT that happens after a
@@ -220,17 +220,17 @@ function do_execute_soon(callback) {
           }
           _do_quit();
         }
       }
       finally {
         do_test_finished();
       }
     }
-  }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
+  });
 }
 
 function do_throw(text, stack) {
   if (!stack)
     stack = Components.stack.caller;
 
   _dump("TEST-UNEXPECTED-FAIL | " + stack.filename + " | " + text +
         " - See following stack:\n");
--- a/mobile/android/tests/browser/robocop/testBrowserDiscovery.js
+++ b/mobile/android/tests/browser/robocop/testBrowserDiscovery.js
@@ -9,30 +9,30 @@ var { classes: Cc, interfaces: Ci, utils
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 // We use a global variable to track the <browser> where the tests are happening
 var browser;
 
 function setHandlerFunc(handler, test) {
   browser.addEventListener("DOMLinkAdded", function(event) {
-    Services.tm.mainThread.dispatch(handler.bind(this, test), Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(handler.bind(this, test));
   }, {once: true});
 }
 
 add_test(function setup_browser() {
   let BrowserApp = Services.wm.getMostRecentWindow("navigator:browser").BrowserApp;
   do_register_cleanup(function cleanup() {
     BrowserApp.closeTab(BrowserApp.getTabForBrowser(browser));
   });
 
   let url = "http://mochi.test:8888/tests/robocop/link_discovery.html";
   browser = BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
   browser.addEventListener("load", function(event) {
-    Services.tm.mainThread.dispatch(run_next_test, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(run_next_test);
   }, {capture: true, once: true});
 });
 
 var searchDiscoveryTests = [
   { text: "rel search discovered" },
   { rel: "SEARCH", text: "rel is case insensitive" },
   { rel: "-search-", pass: false, text: "rel -search- not discovered" },
   { rel: "foo bar baz search quux", text: "rel may contain additional rels separated by spaces" },
--- a/mobile/android/tests/browser/robocop/testHistoryService.js
+++ b/mobile/android/tests/browser/robocop/testHistoryService.js
@@ -74,17 +74,17 @@ add_test(function setup_browser() {
   });
 
   Services.obs.addObserver(visitObserver, "link-visited");
 
   // Load a blank page
   let url = "about:blank";
   gBrowser = BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
   gBrowser.addEventListener("load", function(event) {
-    Services.tm.mainThread.dispatch(run_next_test, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(run_next_test);
   }, {capture: true, once: true});
 });
 
 add_task(function* () {
   // Wait for any initial page loads to be saved to history
   yield sleep(PENDING_VISIT_WAIT);
 
   // Load a simple HTML page with no redirects
--- a/mobile/android/tests/browser/robocop/testTrackingProtection.js
+++ b/mobile/android/tests/browser/robocop/testTrackingProtection.js
@@ -87,17 +87,17 @@ var BrowserApp = Services.wm.getMostRece
 
 // Tests the tracking protection UI in private browsing. By default, tracking protection is
 // enabled in private browsing ("privacy.trackingprotection.pbmode.enabled").
 add_task(function* test_tracking_pb() {
   // Load a blank page
   let browser = BrowserApp.addTab("about:blank", { selected: true, parentId: BrowserApp.selectedTab.id, isPrivate: true }).browser;
   yield new Promise((resolve, reject) => {
     browser.addEventListener("load", function(event) {
-      Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+      Services.tm.dispatchToMainThread(resolve);
     }, {capture: true, once: true});
   });
 
   // Populate and use 'test-track-simple' for tracking protection lookups
   Services.prefs.setCharPref(TABLE, "test-track-simple");
   yield doUpdate();
 
   // Point tab to a test page NOT containing tracking elements
@@ -142,17 +142,17 @@ add_task(function* test_tracking_pb() {
   Services.prefs.clearUserPref("privacy.trackingprotection.pbmode.enabled");
 });
 
 add_task(function* test_tracking_not_pb() {
   // Load a blank page
   let browser = BrowserApp.addTab("about:blank", { selected: true }).browser;
   yield new Promise((resolve, reject) => {
     browser.addEventListener("load", function(event) {
-      Services.tm.mainThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+      Services.tm.dispatchToMainThread(resolve);
     }, {capture: true, once: true});
   });
 
   // Point tab to a test page NOT containing tracking elements
   yield promiseLoadEvent(browser, "http://tracking.example.org/tests/robocop/tracking_good.html");
   EventDispatcher.instance.sendRequest({ type: "Test:Expected", expected: "unknown" });
 
   // Point tab to a test page containing tracking elements (tracking protection UI *should not* be shown)
--- a/mobile/android/tests/browser/robocop/testVideoControls.js
+++ b/mobile/android/tests/browser/robocop/testVideoControls.js
@@ -34,32 +34,32 @@ add_test(function setup_browser() {
   let url = "http://mochi.test:8888/tests/robocop/video_controls.html";
   browser = BrowserApp.addTab(url, { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
   browser.addEventListener("load", function(event) {
     contentDocument = browser.contentDocument;
 
     video = contentDocument.getElementById("video");
     ok(video, "Found the video element");
 
-    Services.tm.mainThread.dispatch(run_next_test, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(run_next_test);
   }, {capture: true, once: true});
 });
 
 add_test(function test_webm() {
   // Load the test video
   video.src = "http://mochi.test:8888/tests/robocop/video-pattern.webm";
 
-  Services.tm.mainThread.dispatch(testLoad, Ci.nsIThread.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread(testLoad);
 });
 
 add_test(function test_ogg() {
   // Load the test video
   video.src = "http://mochi.test:8888/tests/robocop/video-pattern.ogg";
 
-  Services.tm.mainThread.dispatch(testLoad, Ci.nsIThread.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread(testLoad);
 });
 
 function getButtonByAttribute(aName, aValue) {
   let domUtil = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
   let kids = domUtil.getChildrenForNode(video, true);
   let videocontrols = kids[1];
   return contentDocument.getAnonymousElementByAttribute(videocontrols, aName, aValue);
 }
--- a/netwerk/test/browser/browser_nsIFormPOSTActionChannel.js
+++ b/netwerk/test/browser/browser_nsIFormPOSTActionChannel.js
@@ -186,17 +186,17 @@ document.getElementById('form').submit()
         try {
           aListener.onDataAvailable(this, aContext, stream, 0, stream.available());
         } catch(e) {}
         try {
           aListener.onStopRequest(this, aContext, Cr.NS_OK);
         } catch(e) {}
       }
     };
-    Services.tm.currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(runnable);
   },
   asyncOpen2: function(aListener) {
     this.asyncOpen(aListener, null);
   },
 
   /** nsIRequest */
   get name() {
     return this.uri.spec;
--- a/netwerk/test/httpserver/test/test_async_response_sending.js
+++ b/netwerk/test/httpserver/test/test_async_response_sending.js
@@ -1611,17 +1611,17 @@ CopyTest.prototype =
             task();
           }
           catch (e)
           {
             do_throw("exception thrown running task: " + e);
           }
         }
       };
-    gThreadManager.currentThread.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
+    gThreadManager.dispatchToMainThread(event);
   },
 
   /**
    * Adds the given function as a task to be run at a later time.
    *
    * @param task : function() : void
    *   the function to call as a task
    */
--- a/netwerk/test/httpserver/test/test_processasync.js
+++ b/netwerk/test/httpserver/test/test_processasync.js
@@ -280,18 +280,17 @@ function handleAsyncOrdering(request, re
         }
       }
     };
   function step()
   {
     // Use gThreadManager here because it's expedient, *not* because it's
     // intended for public use!  If you do this in client code, expect me to
     // knowingly break your code by changing the variable name.  :-P
-    gThreadManager.currentThread
-                  .dispatch(writeData, Ci.nsIThread.DISPATCH_NORMAL);
+    gThreadManager.dispatchToMainThread(writeData);
   }
   step();
   response.processAsync();
 }
 handlers["/handleAsyncOrdering"] = handleAsyncOrdering;
 
 function stop_handleAsyncOrdering(ch, cx, status, data)
 {
--- a/netwerk/test/httpserver/test/test_seizepower.js
+++ b/netwerk/test/httpserver/test/test_seizepower.js
@@ -42,22 +42,22 @@ function checkException(fun, err, msg)
       do_throw(msg);
     return;
   }
   do_throw(msg);
 }
 
 function callASAPLater(fun)
 {
-  gThreadManager.currentThread.dispatch({
+  gThreadManager.dispatchToMainThread({
     run: function()
     {
       fun();
     }
-  }, Ci.nsIThread.DISPATCH_NORMAL);
+  });
 }
 
 
 /*****************
  * PATH HANDLERS *
  *****************/
 
 function handleRawData(request, response)
--- a/services/common/utils.js
+++ b/services/common/utils.js
@@ -127,17 +127,17 @@ this.CommonUtils = {
    *        Function to invoke.
    * @param thisObj [optional]
    *        Object to bind the callback to.
    */
   nextTick: function nextTick(callback, thisObj) {
     if (thisObj) {
       callback = callback.bind(thisObj);
     }
-    Services.tm.currentThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(callback);
   },
 
   /**
    * Return a promise resolving on some later tick.
    *
    * This a wrapper around Promise.resolve() that prevents stack
    * accumulation and prevents callers from accidentally relying on
    * same-tick promise resolution.
--- a/services/fxaccounts/Credentials.jsm
+++ b/services/fxaccounts/Credentials.jsm
@@ -121,16 +121,15 @@ this.Credentials = Object.freeze({
 
       result.unwrapBKey =
         CryptoUtils.hkdf(quickStretchedPW, hkdfSalt, this.keyWord("unwrapBkey"), hkdfLength);
 
       log.debug("Credentials set up after " + (Date.now() - start) + " ms");
       deferred.resolve(result);
     }
 
-    Services.tm.currentThread.dispatch(runnable,
-        Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(runnable);
     log.debug("Dispatched thread for credentials setup crypto work");
 
     return deferred.promise;
   }
 });
 
--- a/services/sync/modules/SyncedTabs.jsm
+++ b/services/sync/modules/SyncedTabs.jsm
@@ -167,26 +167,26 @@ let SyncedTabsInternal = {
     if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED) {
       log.info("Sync client is not configured, so not attempting a tab sync");
       return Promise.resolve(false);
     }
     // Ask Sync to just do the tabs engine if it can.
     // Sync is currently synchronous, so do it after an event-loop spin to help
     // keep the UI responsive.
     return new Promise((resolve, reject) => {
-      Services.tm.currentThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         try {
           log.info("Doing a tab sync.");
           Weave.Service.sync(["tabs"]);
           resolve(true);
         } catch (ex) {
           log.error("Sync failed", ex);
           reject(ex);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     });
   },
 
   observe(subject, topic, data) {
     log.trace(`observed topic=${topic}, data=${data}, subject=${subject}`);
     switch (topic) {
       case "weave:engine:sync:finish":
         if (data != "tabs") {
--- a/services/sync/tps/extensions/mozmill/resource/stdlib/httpd.js
+++ b/services/sync/tps/extensions/mozmill/resource/stdlib/httpd.js
@@ -490,18 +490,17 @@ nsHttpServer.prototype =
       var stopEvent =
         {
           run: function()
           {
             dumpn("*** _notifyStopped async callback");
             self._notifyStopped();
           }
         };
-      gThreadManager.currentThread
-                    .dispatch(stopEvent, Ci.nsIThread.DISPATCH_NORMAL);
+      gThreadManager.dispatchToMainThread(stopEvent);
     }
   },
 
   // NSIHTTPSERVER
 
   //
   // see nsIHttpServer.start
   //
@@ -2851,18 +2850,17 @@ ServerHandler.prototype =
       catch (e)
       {
         fis.close();
         throw e;
       }
 
       function writeMore()
       {
-        gThreadManager.currentThread
-                      .dispatch(writeData, Ci.nsIThread.DISPATCH_NORMAL);
+        gThreadManager.dispatchToMainThread(writeData);
       }
 
       var input = new BinaryInputStream(fis);
       var output = new BinaryOutputStream(response.bodyOutputStream);
       var writeData =
         {
           run: function()
           {
@@ -3924,23 +3922,23 @@ Response.prototype =
       // happening asynchronously with respect to the actual writing of data to
       // bodyOutputStream, as they currently do; if they happened synchronously,
       // an event which ran before this one could write more data to the
       // response body before we get around to canceling the copier.  We have
       // tests for this in test_seizepower.js, however, and I can't think of a
       // way to handle both cases without removing bodyOutputStream access and
       // moving its effective write(data, length) method onto Response, which
       // would be slower and require more code than this anyway.
-      gThreadManager.currentThread.dispatch({
+      gThreadManager.dispatchToMainThread({
         run: function()
         {
           dumpn("*** canceling copy asynchronously...");
           copier.cancel(Cr.NS_ERROR_UNEXPECTED);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     }
     else
     {
       this.end();
     }
   },
 
   /**
@@ -4679,17 +4677,17 @@ WriteThroughCopier.prototype =
           {
             NS_ASSERT(false,
                       "how are we throwing an exception here?  we control " +
                       "all the callers!  " + e);
           }
         }
       };
 
-    gThreadManager.currentThread.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
+    gThreadManager.dispatchToMainThread(event);
   },
 
   /**
    * Kicks off another wait for more data to be available from the input stream.
    */
   _waitToReadData: function()
   {
     dumpn("*** _waitToReadData");
--- a/testing/mochitest/browser-harness.xul
+++ b/testing/mochitest/browser-harness.xul
@@ -252,17 +252,17 @@
           var Tester = new testWin.Tester(links, gDumper.structuredLogger, testsFinished);
           Tester.start();
         }, testWin);
       }, window);
     }
 
     function executeSoon(callback) {
       let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
-      tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
+      tm.dispatchToMainThread(callback);
     }
 
     function waitForFocus(callback, win) {
       // If "win" is already focused, just call the callback.
       let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
       if (fm.focusedWindow == win) {
         executeSoon(callback);
         return;
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -944,21 +944,21 @@ function testScope(aTester, aTest, expec
     self.todo(a != b, name, "Didn't expect " + a + ", but got it",
               Components.stack.caller);
   };
   this.info = function test_info(name) {
     aTest.addResult(new testMessage(name));
   };
 
   this.executeSoon = function test_executeSoon(func) {
-    Services.tm.mainThread.dispatch({
+    Services.tm.dispatchToMainThread({
       run: function() {
         func();
       }
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
   };
 
   this.waitForExplicitFinish = function test_waitForExplicitFinish() {
     self.__done = false;
   };
 
   this.waitForFocus = function test_waitForFocus(callback, targetWindow, expectBlankPage) {
     self.SimpleTest.waitForFocus(callback, targetWindow, expectBlankPage);
--- a/testing/modules/TestUtils.jsm
+++ b/testing/modules/TestUtils.jsm
@@ -19,17 +19,17 @@ this.EXPORTED_SYMBOLS = [
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 this.TestUtils = {
   executeSoon(callbackFn) {
-    Services.tm.mainThread.dispatch(callbackFn, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(callbackFn);
   },
 
   /**
    * Waits for the specified topic to be observed.
    *
    * @param {string} topic
    *        The topic to observe.
    * @param {function} checkFn [optional]
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -338,19 +338,19 @@ SPConsoleListener.prototype = {
       m.isException   = ((msg.flags & Ci.nsIScriptError.exceptionFlag) === 1);
       m.isStrict      = ((msg.flags & Ci.nsIScriptError.strictFlag) === 1);
     }
 
     Object.freeze(m);
 
     // Run in a separate runnable since console listeners aren't
     // supposed to touch content and this one might.
-    Services.tm.mainThread.dispatch(() => {
+    Services.tm.dispatchToMainThread(() => {
       this.callback.call(undefined, m);
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
 
     if (!m.isScriptError && m.message === "SENTINEL")
       Services.console.unregisterListener(this);
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleListener])
 };
 
@@ -1232,23 +1232,23 @@ SpecialPowersAPI.prototype = {
    */
   _asyncObservers: new WeakMap(),
   addAsyncObserver: function(obs, notification, weak) {
     obs = Cu.waiveXrays(obs);
     if (typeof obs == 'object' && obs.observe.name != 'SpecialPowersCallbackWrapper') {
       obs.observe = wrapCallback(obs.observe);
     }
     let asyncObs = (...args) => {
-      Services.tm.mainThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         if (typeof obs == 'function') {
           obs.call(undefined, ...args);
         } else {
           obs.observe.call(undefined, ...args);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     };
     this._asyncObservers.set(obs, asyncObs);
     Services.obs.addObserver(asyncObs, notification, weak);
   },
   removeAsyncObserver: function(obs, notification) {
     let asyncObs = this._asyncObservers.get(Cu.waiveXrays(obs));
     Services.obs.removeObserver(asyncObs, notification);
   },
@@ -2134,42 +2134,42 @@ SpecialPowersAPI.prototype = {
    * chrome-privileged and allowed to run inside SystemGroup
    */
 
   doUrlClassify(principal, eventTarget, tpEnabled, callback) {
     let classifierService =
       Cc["@mozilla.org/url-classifier/dbservice;1"].getService(Ci.nsIURIClassifier);
 
     let wrapCallback = (...args) => {
-      Services.tm.mainThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         if (typeof callback == 'function') {
           callback.call(undefined, ...args);
         } else {
           callback.onClassifyComplete.call(undefined, ...args);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     };
 
     return classifierService.classify(unwrapIfWrapped(principal), eventTarget,
                                       tpEnabled, wrapCallback);
   },
 
   // TODO: Bug 1353701 - Supports custom event target for labelling.
   doUrlClassifyLocal(uri, tables, callback) {
     let classifierService =
       Cc["@mozilla.org/url-classifier/dbservice;1"].getService(Ci.nsIURIClassifier);
 
     let wrapCallback = (...args) => {
-      Services.tm.mainThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         if (typeof callback == 'function') {
           callback.call(undefined, ...args);
         } else {
           callback.onClassifyComplete.call(undefined, ...args);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     };
 
     return classifierService.asyncClassifyLocalWithTables(unwrapIfWrapped(uri),
                                                           tables,
                                                           wrapCallback);
   },
 
 };
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -692,17 +692,17 @@ function do_timeout(delay, func) {
 }
 
 function do_execute_soon(callback, aName) {
   let funcName = (aName ? aName : callback.name);
   do_test_pending(funcName);
   var tm = Components.classes["@mozilla.org/thread-manager;1"]
                      .getService(Components.interfaces.nsIThreadManager);
 
-  tm.mainThread.dispatch({
+  tm.dispatchToMainThread({
     run: function() {
       try {
         callback();
       } catch (e) {
         // do_check failures are already logged and set _quit to true and throw
         // NS_ERROR_ABORT. If both of those are true it is likely this exception
         // has already been logged so there is no need to log it again. It's
         // possible that this will mask an NS_ERROR_ABORT that happens after a
@@ -717,17 +717,17 @@ function do_execute_soon(callback, aName
                                  stack);
           _do_quit();
         }
       }
       finally {
         do_test_finished(funcName);
       }
     }
-  }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
+  });
 }
 
 /**
  * Shows an error message and the current stack and aborts the test.
  *
  * @param error  A message string or an Error object.
  * @param stack  null or nsIStackFrame object or a string containing
  *               \n separated stack lines (as in Error().stack).
--- a/toolkit/components/addoncompat/RemoteAddonsChild.jsm
+++ b/toolkit/components/addoncompat/RemoteAddonsChild.jsm
@@ -349,17 +349,17 @@ AboutProtocolChannel.prototype = {
         try {
           listener.onDataAvailable(this, context, stream, 0, stream.available());
         } catch (e) {}
         try {
           listener.onStopRequest(this, context, Cr.NS_OK);
         } catch (e) {}
       }
     };
-    Services.tm.currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(runnable);
   },
 
   asyncOpen2(listener) {
     // throws an error if security checks fail
     var outListener = contentSecManager.performSecurityCheck(this, listener);
     this.asyncOpen(outListener, null);
   },
 
--- a/toolkit/components/addoncompat/tests/addon/bootstrap.js
+++ b/toolkit/components/addoncompat/tests/addon/bootstrap.js
@@ -283,17 +283,17 @@ function testAboutModuleRegistration() {
           try {
             listener.onDataAvailable(this, context, stream, 0, stream.available());
           } catch (e) {}
           try {
             listener.onStopRequest(this, context, Cr.NS_OK);
           } catch (e) {}
         }
       };
-      Services.tm.currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
+      Services.tm.dispatchToMainThread(runnable);
     },
 
     asyncOpen2(listener) {
       // throws an error if security checks fail
       var outListener = contentSecManager.performSecurityCheck(this, listener);
       return this.asyncOpen(outListener, null);
     },
 
--- a/toolkit/components/contentprefs/ContentPrefService2.jsm
+++ b/toolkit/components/contentprefs/ContentPrefService2.jsm
@@ -779,18 +779,17 @@ ContentPrefService2.prototype = {
       var groupURI = Services.io.newURI(groupStr);
     } catch (err) {
       return groupStr;
     }
     return this._cps._grouper.group(groupURI);
   },
 
   _schedule: function CPS2__schedule(fn) {
-    Services.tm.mainThread.dispatch(fn.bind(this),
-                                    Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(fn.bind(this));
   },
 
   addObserverForName: function CPS2_addObserverForName(name, observer) {
     this._cps._addObserver(name, observer);
   },
 
   removeObserverForName: function CPS2_removeObserverForName(name, observer) {
     this._cps._removeObserver(name, observer);
--- a/toolkit/components/contentprefs/nsContentPrefService.js
+++ b/toolkit/components/contentprefs/nsContentPrefService.js
@@ -569,17 +569,17 @@ ContentPrefService.prototype = {
         AND settings.name = :setting
       `);
 
     return this.__stmtSelectPref;
   },
 
   _scheduleCallback(func) {
     let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
-    tm.mainThread.dispatch(func, Ci.nsIThread.DISPATCH_NORMAL);
+    tm.dispatchToMainThread(func);
   },
 
   _selectPref: function ContentPrefService__selectPref(aGroup, aSetting, aCallback) {
     let value = undefined;
     if (this._cache.has(aGroup, aSetting)) {
       value = this._cache.get(aGroup, aSetting);
       if (aCallback) {
         this._scheduleCallback(function() { aCallback.onResult(value); });
--- a/toolkit/components/filepicker/nsFilePicker.js
+++ b/toolkit/components/filepicker/nsFilePicker.js
@@ -196,17 +196,17 @@ nsFilePicker.prototype = {
   appendFilter(title, extensions) {
     this.mFilterTitles.push(title);
     this.mFilters.push(extensions);
   },
 
   open(aFilePickerShownCallback) {
     var tm = Components.classes["@mozilla.org/thread-manager;1"]
                        .getService(Components.interfaces.nsIThreadManager);
-    tm.mainThread.dispatch(() => {
+    tm.dispatchToMainThread(() => {
       let result = Components.interfaces.nsIFilePicker.returnCancel;
       try {
         result = this.show();
       } catch (ex) {
       }
 
       let promises = [];
 
@@ -243,17 +243,17 @@ nsFilePicker.prototype = {
         }
       }
 
       Promise.all(promises).then(() => {
         if (aFilePickerShownCallback) {
           aFilePickerShownCallback.done(result);
         }
       });
-    }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
+    });
   },
 
   show() {
     var o = {};
     o.title = this.mTitle;
     o.mode = this.mMode;
     o.displayDirectory = this.mDisplayDirectory;
     o.defaultString = this.mDefaultString;
--- a/toolkit/components/formautofill/FormAutofillContentService.js
+++ b/toolkit/components/formautofill/FormAutofillContentService.js
@@ -241,17 +241,17 @@ FormHandler.prototype = {
     }
   },
 
   /**
    * Waits for one tick of the event loop before resolving the returned promise.
    */
   waitForTick() {
     return new Promise(function(resolve) {
-      Services.tm.currentThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+      Services.tm.dispatchToMainThread(resolve);
     });
   },
 };
 
 /**
  * Implements a service used by DOM content to request Form Autofill, in
  * particular when the requestAutocomplete method of Form objects is invoked.
  */
--- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
@@ -175,17 +175,17 @@ LoginManagerPromptFactory.prototype = {
 
       // just make the runnable cancel all consumers
       runnable.cancel = true;
     } else {
       this._asyncPromptInProgress = true;
       prompt.inProgress = true;
     }
 
-    Services.tm.mainThread.dispatch(runnable, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(runnable);
     this.log("_doAsyncPrompt:run dispatched");
   },
 
 
   _cancelPendingPrompts() {
     this.log("Canceling all pending prompts...");
     var asyncPrompts = this._asyncPrompts;
     this.__proto__._asyncPrompts = {};
--- a/toolkit/components/perfmonitoring/PerformanceWatcher.jsm
+++ b/toolkit/components/perfmonitoring/PerformanceWatcher.jsm
@@ -269,27 +269,27 @@ function BufferedObserver(listener) {
   this._isDispatching = false;
   this._pending = null;
 }
 BufferedObserver.prototype = Object.create(Observer.prototype);
 BufferedObserver.prototype.observe = function(source, details) {
   this._buffer.push({source, details});
   if (!this._isDispatching) {
     this._isDispatching = true;
-    Services.tm.mainThread.dispatch(() => {
+    Services.tm.dispatchToMainThread(() => {
       // Grab buffer, in case something in the listener could modify it.
       let buffer = this._buffer;
       this._buffer = [];
 
       // As of this point, any further observations need to use the new buffer
       // and a new dispatcher.
       this._isDispatching = false;
 
       this._listener(buffer);
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
   }
 };
 
 this.PerformanceWatcher = {
   /**
    * Add a listener informed whenever we receive a slow performance alert
    * in the application.
    *
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -1555,51 +1555,51 @@ this.PlacesUtils = {
    * @param aCharset character-set value.
    * @return {Promise}
    */
   setCharsetForURI: function PU_setCharsetForURI(aURI, aCharset) {
     let deferred = Promise.defer();
 
     // Delaying to catch issues with asynchronous behavior while waiting
     // to implement asynchronous annotations in bug 699844.
-    Services.tm.mainThread.dispatch(function() {
+    Services.tm.dispatchToMainThread(function() {
       if (aCharset && aCharset.length > 0) {
         PlacesUtils.annotations.setPageAnnotation(
           aURI, PlacesUtils.CHARSET_ANNO, aCharset, 0,
           Ci.nsIAnnotationService.EXPIRE_NEVER);
       } else {
         PlacesUtils.annotations.removePageAnnotation(
           aURI, PlacesUtils.CHARSET_ANNO);
       }
       deferred.resolve();
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
 
     return deferred.promise;
   },
 
   /**
    * Gets the last saved character-set for a URI.
    *
    * @param aURI nsIURI
    * @return {Promise}
    * @resolve a character-set or null.
    */
   getCharsetForURI: function PU_getCharsetForURI(aURI) {
     let deferred = Promise.defer();
 
-    Services.tm.mainThread.dispatch(function() {
+    Services.tm.dispatchToMainThread(function() {
       let charset = null;
 
       try {
         charset = PlacesUtils.annotations.getPageAnnotation(aURI,
                                                             PlacesUtils.CHARSET_ANNO);
       } catch (ex) { }
 
       deferred.resolve(charset);
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
 
     return deferred.promise;
   },
 
   /**
    * Promised wrapper for mozIAsyncHistory::getPlacesInfo for a single place.
    *
    * @param aPlaceIdentifier
@@ -1970,17 +1970,17 @@ this.PlacesUtils = {
 
       if (item.type == this.TYPE_X_MOZ_PLACE_CONTAINER)
         parentsMap.set(item.guid, item);
 
       // With many bookmarks we end up stealing the CPU - even with yielding!
       // So we let everyone else have a go every few items (bug 1186714).
       if (++yieldCounter % 50 == 0) {
         yield new Promise(resolve => {
-          Services.tm.currentThread.dispatch(resolve, Ci.nsIThread.DISPATCH_NORMAL);
+          Services.tm.dispatchToMainThread(resolve);
         });
       }
     }
 
     return rootItem;
   })
 };
 
--- a/toolkit/components/places/nsLivemarkService.js
+++ b/toolkit/components/places/nsLivemarkService.js
@@ -671,19 +671,19 @@ Livemark.prototype = {
       }
     }
 
     for (let [ container, observer ] of this._resultObservers) {
       if (this._nodes.has(container)) {
         let nodes = this._nodes.get(container);
         for (let node of nodes) {
           if (!aURI || node.uri == aURI.spec) {
-            Services.tm.mainThread.dispatch(() => {
+            Services.tm.dispatchToMainThread(() => {
               observer.nodeHistoryDetailsChanged(node, 0, aVisitedStatus);
-            }, Ci.nsIThread.DISPATCH_NORMAL);
+            });
           }
         }
       }
     }
   },
 
   /**
    * Terminates the livemark entry, cancelling any ongoing load.
--- a/toolkit/components/places/tests/bookmarks/test_async_observers.js
+++ b/toolkit/components/places/tests/bookmarks/test_async_observers.js
@@ -128,24 +128,24 @@ add_task(function* shutdown() {
   // Notice this code is not using helpers cause it depends on a very specific
   // order, a change in the helpers code could make this test useless.
   let deferred = Promise.defer();
 
   Services.obs.addObserver(function onNotification() {
     Services.obs.removeObserver(onNotification, "places-will-close-connection");
     do_check_true(true, "Observed fake places shutdown");
 
-    Services.tm.mainThread.dispatch(() => {
+    Services.tm.dispatchToMainThread(() => {
       // WARNING: this is very bad, never use out of testing code.
       PlacesUtils.bookmarks.QueryInterface(Ci.nsINavHistoryObserver)
                            .onPageChanged(NetUtil.newURI("http://book.ma.rk/"),
                                           Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON,
                                           "test", "test");
       deferred.resolve(promiseTopicObserved("places-connection-closed"));
-    }, Ci.nsIThread.DISPATCH_NORMAL);
+    });
   }, "places-will-close-connection");
   shutdownPlaces();
 
   yield deferred.promise;
 });
 
 function run_test() {
   // Add multiple bookmarks to the same uri.
--- a/toolkit/components/prompts/content/tabprompts.xml
+++ b/toolkit/components/prompts/content/tabprompts.xml
@@ -279,21 +279,20 @@
                 // https://bugzilla.mozilla.org/show_bug.cgi?id=1167575#c35 : we
                 // get here off processing of an OS event and will also process
                 // one more Gecko runnable before we break out of the event loop
                 // spin whoever posted the prompt is doing.  If we do all our
                 // work sync, we will exit modal state _before_ processing that
                 // runnable, and if exiting moral state posts a runnable we will
                 // incorrectly process that runnable before leaving our event
                 // loop spin.
-                Services.tm.mainThread.dispatch(() => {
+                Services.tm.dispatchToMainThread(() => {
                     this.Dialog["onButton" + buttonNum]();
                     this.shutdownPrompt();
-                  },
-                  Ci.nsIThread.DISPATCH_NORMAL);
+                  });
             ]]>
             </body>
         </method>
 
         <method name="onKeyAction">
             <parameter name="action"/>
             <parameter name="event"/>
             <body>
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -2632,17 +2632,17 @@ ParseSubmissionResult.prototype = {
   },
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISearchParseSubmissionResult]),
 }
 
 const gEmptyParseSubmissionResult =
       Object.freeze(new ParseSubmissionResult(null, "", -1, 0));
 
 function executeSoon(func) {
-  Services.tm.mainThread.dispatch(func, Ci.nsIThread.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread(func);
 }
 
 /**
  * Check for sync initialization has completed or not.
  *
  * @param {aPromise} A promise.
  *
  * @returns the value returned by the invoked method.
--- a/toolkit/components/telemetry/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/TelemetrySession.jsm
@@ -1969,22 +1969,22 @@ var Impl = {
       // Check whether debugger was attached during startup
       let debugService = Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2);
       gWasDebuggerAttached = debugService.isDebuggerAttached;
       this.gatherStartup();
       break;
     case "idle-daily":
       // Enqueue to main-thread, otherwise components may be inited by the
       // idle-daily category and miss the gather-telemetry notification.
-      Services.tm.mainThread.dispatch((function() {
+      Services.tm.dispatchToMainThread((function() {
         // Notify that data should be gathered now.
         // TODO: We are keeping this behaviour for now but it will be removed as soon as
         // bug 1127907 lands.
         Services.obs.notifyObservers(null, "gather-telemetry");
-      }), Ci.nsIThread.DISPATCH_NORMAL);
+      }));
       break;
 
     case "application-background":
       if (AppConstants.platform !== "android") {
         break;
       }
       // On Android, we can get killed without warning once we are in the background,
       // but we may also submit data and/or come back into the foreground without getting
--- a/toolkit/components/telemetry/tests/unit/head.js
+++ b/toolkit/components/telemetry/tests/unit/head.js
@@ -81,18 +81,17 @@ const PingServer = {
     this._defers = [ PromiseUtils.defer() ];
     this._currentDeferred = 0;
   },
 
   promiseNextRequest() {
     const deferred = this._defers[this._currentDeferred++];
     // Send the ping to the consumer on the next tick, so that the completion gets
     // signaled to Telemetry.
-    return new Promise(r => Services.tm.currentThread.dispatch(() => r(deferred.promise),
-                                                               Ci.nsIThread.DISPATCH_NORMAL));
+    return new Promise(r => Services.tm.dispatchToMainThread(() => r(deferred.promise)));
   },
 
   promiseNextPing() {
     return this.promiseNextRequest().then(request => decodeRequestPayload(request));
   },
 
   async promiseNextRequests(count) {
     let results = [];
@@ -310,17 +309,17 @@ if (runningInParent) {
   Services.prefs.setBoolPref("datareporting.healthreport.uploadEnabled", true);
   // Many tests expect the shutdown ping to not be sent on shutdown and will fail
   // if receive an unexpected ping. Let's globally disable the shutdown ping sender:
   // the relevant tests will enable this pref when needed.
   Services.prefs.setBoolPref("toolkit.telemetry.shutdownPingSender.enabled", false);
 
 
   fakePingSendTimer((callback, timeout) => {
-    Services.tm.mainThread.dispatch(() => callback(), Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(() => callback());
   },
   () => {});
 
   // This gets imported via fakeNow();
   /* global TelemetrySend */
   do_register_cleanup(() => TelemetrySend.shutdown());
 }
 
--- a/toolkit/components/telemetry/tests/unit/test_PingSender.js
+++ b/toolkit/components/telemetry/tests/unit/test_PingSender.js
@@ -71,18 +71,17 @@ add_task(function* test_pingSender() {
   let deferred404Hit = PromiseUtils.defer();
   let hitCount = 0;
   failingServer.registerPathHandler("/lookup_fail", (metadata, response) => {
     response.setStatusLine("1.1", 404, "Not Found");
     hitCount++;
 
     if (hitCount >= 2) {
       // Resolve the promise on the next tick.
-      Services.tm.currentThread.dispatch(() => deferred404Hit.resolve(),
-                                         Ci.nsIThread.DISPATCH_NORMAL);
+      Services.tm.dispatchToMainThread(() => deferred404Hit.resolve());
     }
   });
   failingServer.start(-1);
 
   // Try to send the ping twice using the pingsender (we expect 404 both times).
   const errorUrl = "http://localhost:" + failingServer.identity.primaryPort + "/lookup_fail";
   Telemetry.runPingSender(errorUrl, pingPath);
   Telemetry.runPingSender(errorUrl, pingPath);
--- a/toolkit/components/thumbnails/BackgroundPageThumbs.jsm
+++ b/toolkit/components/thumbnails/BackgroundPageThumbs.jsm
@@ -259,19 +259,19 @@ const BackgroundPageThumbs = {
       if (curCapture && curCapture.pending) {
         // Continue queue processing by calling curCapture._done().  Do it after
         // this crashed listener returns, though.  A new browser will be created
         // immediately (on the same stack as the _done call stack) if there are
         // any more queued-up captures, and that seems to mess up the new
         // browser's message manager if it happens on the same stack as the
         // listener.  Trying to send a message to the manager in that case
         // throws NS_ERROR_NOT_INITIALIZED.
-        Services.tm.currentThread.dispatch(() => {
+        Services.tm.dispatchToMainThread(() => {
           curCapture._done(null, TEL_CAPTURE_DONE_CRASHED);
-        }, Ci.nsIEventTarget.DISPATCH_NORMAL);
+        });
       }
       // else: we must have been idle and not currently doing a capture (eg,
       // maybe a GC or similar crashed) - so there's no need to attempt a
       // queue restart - the next capture request will set everything up.
     });
 
     browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
     this._thumbBrowser = browser;
@@ -497,10 +497,10 @@ Capture.nextID = 0;
  * @param value        The value to add.
  */
 function tel(histogramID, value) {
   let id = TELEMETRY_HISTOGRAM_ID_PREFIX + histogramID;
   Services.telemetry.getHistogramById(id).add(value);
 }
 
 function schedule(callback) {
-  Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread(callback);
 }
--- a/toolkit/components/url-classifier/nsUrlClassifierHashCompleter.js
+++ b/toolkit/components/url-classifier/nsUrlClassifierHashCompleter.js
@@ -227,17 +227,17 @@ HashCompleter.prototype = {
     }
 
     if (!this._nextGethashTimeMs[aGethashUrl]) {
       this._nextGethashTimeMs[aGethashUrl] = 0;
     }
 
     // Start off this request. Without dispatching to a thread, every call to
     // complete makes an individual HTTP request.
-    Services.tm.currentThread.dispatch(this, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(this);
   },
 
   // This is called after several calls to |complete|, or after the
   // currentRequest has finished.  It starts off the HTTP request by making a
   // |begin| call to the HashCompleterRequest.
   run: function() {
     // Clear everything on shutdown
     if (this._shuttingDown) {
@@ -268,17 +268,17 @@ HashCompleter.prototype = {
       }
     }
   },
 
   // Pass the server response status to the RequestBackoff for the given
   // gethashUrl and fetch the next pending request, if there is one.
   finishRequest: function(url, aStatus) {
     this._backoffs[url].noteServerResponse(aStatus);
-    Services.tm.currentThread.dispatch(this, Ci.nsIThread.DISPATCH_NORMAL);
+    Services.tm.dispatchToMainThread(this);
   },
 
   // Returns true if we can make a request from the given url, false otherwise.
   canMakeRequest: function(aGethashUrl) {
     return this._backoffs[aGethashUrl].canMakeRequest() &&
            Date.now() >= this._nextGethashTimeMs[aGethashUrl];
   },
 
--- a/toolkit/content/browser-content.js
+++ b/toolkit/content/browser-content.js
@@ -651,26 +651,26 @@ var Printing = {
       // to generate header/footer content correctly, since simplified tab has
       // "about:blank" as its URI.
       if (printSettings && simplifiedMode)
         printSettings.docURL = contentWindow.document.baseURI;
 
       // The print preview docshell will be in a different TabGroup,
       // so we run it in a separate runnable to avoid touching a
       // different TabGroup in our own runnable.
-      Services.tm.mainThread.dispatch(() => {
+      Services.tm.dispatchToMainThread(() => {
         try {
           docShell.printPreview.printPreview(printSettings, contentWindow, this);
         } catch (error) {
           // This might fail if we, for example, attempt to print a XUL document.
           // In that case, we inform the parent to bail out of print preview.
           Components.utils.reportError(error);
           notifyEntered(error);
         }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
+      });
     } catch (error) {
       // This might fail if we, for example, attempt to print a XUL document.
       // In that case, we inform the parent to bail out of print preview.
       Components.utils.reportError(error);
       notifyEntered(error);
     }
   },
 
--- a/toolkit/content/contentAreaUtils.js
+++ b/toolkit/content/contentAreaUtils.js
@@ -685,19 +685,19 @@ function promiseTargetFile(aFpP, /* opti
       return true;
     }
 
     // We must prompt for the file name explicitly.
     // If we must prompt because we were asked to...
     let deferred = Promise.defer();
     if (useDownloadDir) {
       // Keep async behavior in both branches
-      Services.tm.mainThread.dispatch(function() {
+      Services.tm.dispatchToMainThread(function() {
         deferred.resolve(null);
-      }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
+      });
     } else {
       downloadLastDir.getFileAsync(aRelatedURI, function getFileAsyncCB(aFile) {
         deferred.resolve(aFile);
       });
     }
     let file = yield deferred.promise;
     if (file && (yield OS.File.exists(file.path))) {
       dir = file;
--- a/toolkit/content/widgets/remote-browser.xml
+++ b/toolkit/content/widgets/remote-browser.xml
@@ -341,17 +341,17 @@
 
           let timedOut = false;
           function timeout() {
             if (!responded) {
               timedOut = true;
             }
 
             // Dispatch something to ensure that the main thread wakes up.
-            Services.tm.mainThread.dispatch(function() {}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
+            Services.tm.dispatchToMainThread(function() {});
           }
 
           let timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
           timer.initWithCallback(timeout, kTimeout, timer.TYPE_ONE_SHOT);
 
           while (!finished && !timedOut) {
             Services.tm.currentThread.processNextEvent(true);
           }
--- a/toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js
+++ b/toolkit/forgetaboutsite/test/unit/test_removeDataFromDomain.js
@@ -377,19 +377,19 @@ function waitForPurgeNotification() {
   let deferred = Promise.defer();
 
   let observer = {
     observe(aSubject, aTopic, aData) {
       Services.obs.removeObserver(observer, "browser:purge-domain-data");
       // test_storage_cleared needs this extra executeSoon because
       // the DOMStorage clean-up is also listening to this same observer
       // which is run synchronously.
-      Services.tm.mainThread.dispatch(function() {
+      Services.tm.dispatchToMainThread(function() {
         deferred.resolve();
-      }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
+      });
     }
   };
   Services.obs.addObserver(observer, "browser:purge-domain-data");
 
   return deferred.promise;
 }
 
 // Content Preferences
--- a/toolkit/modules/PropertyListUtils.jsm
+++ b/toolkit/modules/PropertyListUtils.jsm
@@ -85,17 +85,17 @@ this.PropertyListUtils = Object.freeze({
   read: function PLU_read(aFile, aCallback) {
     if (!(aFile instanceof Ci.nsILocalFile || aFile instanceof File))
       throw new Error("aFile is not a file object");
     if (typeof(aCallback) != "function")
       throw new Error("Invalid value for aCallback");
 
     // We guarantee not to throw directly for any other exceptions, and always
     // call aCallback.
-    Services.tm.mainThread.dispatch(function() {
+    Services.tm.dispatchToMainThread(function() {
       let self = this;
       function readDOMFile(aFile) {
         let fileReader = new FileReader();
         let onLoadEnd = function() {
           let root = null;
           try {
             fileReader.removeEventListener("loadend", onLoadEnd);
             if (fileReader.readyState != fileReader.DONE)
@@ -121,17 +121,17 @@ this.PropertyListUtils = Object.freeze({
           });
           return;
         }
         readDOMFile(aFile);
       } catch (ex) {
         aCallback(null);
         throw ex;
       }
-    }.bind(this), Ci.nsIThread.DISPATCH_NORMAL);
+    }.bind(this));
   },
 
   /**
    * DO NOT USE ME.  Once Bug 718189 is fixed, this method won't be public.
    *
    * Synchronously read an ArrayBuffer contents as a property list.
    */
   _readFromArrayBufferSync: function PLU__readFromArrayBufferSync(aBuffer) {
--- a/toolkit/modules/Troubleshoot.jsm
+++ b/toolkit/modules/Troubleshoot.jsm
@@ -146,18 +146,17 @@ this.Troubleshoot = {
    */
   snapshot: function snapshot(done) {
     let snapshot = {};
     let numPending = Object.keys(dataProviders).length;
     function providerDone(providerName, providerData) {
       snapshot[providerName] = providerData;
       if (--numPending == 0)
         // Ensure that done is always and truly called asynchronously.
-        Services.tm.mainThread.dispatch(done.bind(null, snapshot),
-                                        Ci.nsIThread.DISPATCH_NORMAL);
+        Services.tm.dispatchToMainThread(done.bind(null, snapshot));
     }
     for (let name in dataProviders) {
       try {
         dataProviders[name](providerDone.bind(null, name));
       } catch (err) {
         let msg = "Troubleshoot data provider failed: " + name + "\n" + err;
         Cu.reportError(msg);
         providerDone(name, msg);
--- a/toolkit/modules/addons/WebRequest.jsm
+++ b/toolkit/modules/addons/WebRequest.jsm
@@ -62,17 +62,17 @@ var RequestId = {
   },
 
   get(channel) {
     return (channel && getData(channel).requestId) || this.create(channel);
   },
 };
 
 function runLater(job) {
-  Services.tm.currentThread.dispatch(job, Ci.nsIEventTarget.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread(job);
 }
 
 function parseFilter(filter) {
   if (!filter) {
     filter = {};
   }
 
   // FIXME: Support windowId filtering.
--- a/toolkit/modules/tests/xpcshell/test_task.js
+++ b/toolkit/modules/tests/xpcshell/test_task.js
@@ -23,18 +23,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/Task.jsm");
 
 /**
  * Returns a promise that will be resolved with the given value, when an event
  * posted on the event loop of the main thread is processed.
  */
 function promiseResolvedLater(aValue) {
   let deferred = Promise.defer();
-  Services.tm.mainThread.dispatch(() => deferred.resolve(aValue),
-                                  Ci.nsIThread.DISPATCH_NORMAL);
+  Services.tm.dispatchToMainThread(() => deferred.resolve(aValue));
   return deferred.promise;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Tests
 
 function run_test()
 {
--- a/toolkit/mozapps/downloads/DownloadLastDir.jsm
+++ b/toolkit/mozapps/downloads/DownloadLastDir.jsm
@@ -143,18 +143,17 @@ DownloadLastDir.prototype = {
       return gDownloadLastDirFile;
     }
     return readLastDirPref();
   },
 
   getFileAsync(aURI, aCallback) {
     let plainPrefFile = this._getLastFile();
     if (!aURI || !isContentPrefEnabled()) {
-      Services.tm.mainThread.dispatch(() => aCallback(plainPrefFile),
-                                      Components.interfaces.nsIThread.DISPATCH_NORMAL);
+      Services.tm.dispatchToMainThread(() => aCallback(plainPrefFile));
       return;
     }
 
     let uri = aURI instanceof Components.interfaces.nsIURI ? aURI.spec : aURI;
     let cps2 = Components.classes["@mozilla.org/content-pref/service;1"]
                          .getService(Components.interfaces.nsIContentPrefService2);
     let result = null;
     cps2.getByDomainAndName(uri, LAST_DIR_PREF, this.fakeContext, {
--- a/toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedRecovery.js
+++ b/toolkit/mozapps/update/tests/unit_aus_update/downloadInterruptedRecovery.js
@@ -98,17 +98,17 @@ IncrementalDownload.prototype = {
     this._finalURI = uri;
   },
 
   start(observer, ctxt) {
     let tm = Cc["@mozilla.org/thread-manager;1"].
              getService(Ci.nsIThreadManager);
     // Do the actual operation async to give a chance for observers
     // to add themselves.
-    tm.mainThread.dispatch(function() {
+    tm.dispatchToMainThread(function() {
       this._observer = observer.QueryInterface(Ci.nsIRequestObserver);
       this._ctxt = ctxt;
       this._observer.onStartRequest(this, this._ctxt);
       let mar = getTestDirFile(FILE_SIMPLE_MAR);
       mar.copyTo(this._destination.parent, this._destination.leafName);
       let status = Cr.NS_OK;
       switch (gIncrementalDownloadErrorType++) {
         case 0:
@@ -124,25 +124,25 @@ IncrementalDownload.prototype = {
           status = Cr.NS_OK;
           break;
         case 4:
           status = Cr.NS_ERROR_OFFLINE;
           // After we report offline, we want to eventually show offline
           // status being changed to online.
           let tm2 = Cc["@mozilla.org/thread-manager;1"].
                     getService(Ci.nsIThreadManager);
-          tm2.mainThread.dispatch(function() {
+          tm2.dispatchToMainThread(function() {
             Services.obs.notifyObservers(gAUS,
                                          "network:offline-status-changed",
                                          "online");
-          }, Ci.nsIThread.DISPATCH_NORMAL);
+          });
           break;
       }
       this._observer.onStopRequest(this, this._ctxt, status);
-    }.bind(this), Ci.nsIThread.DISPATCH_NORMAL);
+    }.bind(this));
   },
 
   get URI() {
     return this._URI;
   },
 
   get currentSize() {
     throw Cr.NS_ERROR_NOT_IMPLEMENTED;
--- a/xpcom/tests/unit/test_bug656331.js
+++ b/xpcom/tests/unit/test_bug656331.js
@@ -26,14 +26,14 @@ function run_test() {
 
   let manifest = do_get_file('components/bug656331.manifest');
   registerAppManifest(manifest);
 
   do_check_false("{f18fb09b-28b4-4435-bc5b-8027f18df743}" in Components.classesByID);
 
   do_test_pending();
   Components.classes["@mozilla.org/thread-manager;1"].
-    getService(Ci.nsIThreadManager).mainThread.dispatch(function() {
+    getService(Ci.nsIThreadManager).dispatchToMainThread(function() {
       cs.unregisterListener(kConsoleListener);
       do_check_true(gFound);
       do_test_finished();
-    }, 0);
+    });
 }