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 403830 cd981920d0ef8adf66e504b718a4208dc03c7a4c
parent 403829 d2a26a27c192d43ffec287c618a9926ba0a75d67
child 403831 d65b53cf8fd9f7747c7ee4e3ea96f12434917daa
child 403845 3f319382720cc8fa8257b25b7513546e6113791e
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1355161
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 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);
+    });
 }