From d10d03d07698ba2c7ec5b63e832feb6ec1fa6641 Mon Sep 17 00:00:00 2001 From: Simon Giesecke Date: Mon, 23 Nov 2020 16:10:41 +0000 Subject: [PATCH] Bug 1676365 - Move SpinEventLoopUntil to separate header. r=#xpcom-reviewers Differential Revision: https://phabricator.services.mozilla.com/D96556 Depends on D96554 --- devtools/platform/nsJSInspector.cpp | 2 +- dom/base/nsGlobalWindowInner.cpp | 1 + dom/base/nsGlobalWindowOuter.cpp | 1 + dom/cache/Manager.cpp | 1 + dom/filehandle/ActorsParent.cpp | 1 + dom/indexedDB/ActorsParent.cpp | 1 + dom/ipc/ContentChild.cpp | 1 + dom/localstorage/ActorsParent.cpp | 1 + dom/localstorage/LSObject.cpp | 1 + dom/media/fuzz/FuzzMedia.cpp | 1 + dom/media/gmp/GMPServiceParent.cpp | 1 + dom/media/gtest/GMPTestMonitor.h | 1 + dom/media/gtest/TestAudioTrackGraph.cpp | 1 + dom/media/gtest/TestCDMStorage.cpp | 1 + dom/media/gtest/TestDriftCompensation.cpp | 1 + dom/media/gtest/TestMediaDataDecoder.cpp | 1 + dom/media/gtest/TestMediaDataEncoder.cpp | 1 + dom/plugins/base/nsPluginHost.cpp | 1 + dom/quota/ActorsParent.cpp | 1 + dom/simpledb/ActorsParent.cpp | 1 + dom/storage/StorageObserver.cpp | 1 + dom/xhr/XMLHttpRequestMainThread.cpp | 1 + .../pref/autoconfig/src/nsAutoConfig.cpp | 1 + gfx/layers/ipc/CompositorBridgeChild.cpp | 1 + gfx/layers/ipc/CompositorThread.cpp | 1 + ipc/glue/BackgroundImpl.cpp | 1 + layout/base/nsDocumentViewer.cpp | 1 + layout/printing/ipc/RemotePrintJobChild.cpp | 1 + .../gtest/mediapipeline_unittest.cpp | 1 + modules/libpref/Preferences.cpp | 1 + netwerk/base/ProxyAutoConfig.cpp | 1 + netwerk/base/nsAsyncRedirectVerifyHelper.cpp | 1 + netwerk/base/nsSyncStreamListener.cpp | 1 + netwerk/protocol/http/nsHttpConnectionMgr.cpp | 1 + netwerk/test/fuzz/FuzzingStreamListener.h | 2 +- netwerk/test/fuzz/TestFtpFuzzing.cpp | 1 + netwerk/test/fuzz/TestHttpFuzzing.cpp | 1 + netwerk/test/fuzz/TestWebsocketFuzzing.cpp | 1 + .../test/gtest/TestBufferedInputStream.cpp | 1 + netwerk/test/gtest/TestCommon.h | 1 + netwerk/test/gtest/TestMIMEInputStream.cpp | 1 + .../TestPartiallySeekableInputStream.cpp | 1 + storage/mozStorageConnection.cpp | 1 + storage/mozStorageService.cpp | 1 + toolkit/components/places/Database.cpp | 1 + .../places/tests/gtest/places_test_harness.h | 1 + .../places/tests/gtest/test_IHistory.cpp | 1 + .../printingui/ipc/nsPrintingProxy.cpp | 1 + .../url-classifier/tests/gtest/Common.cpp | 1 + toolkit/xre/ProfileReset.cpp | 1 + .../preload/gtest/TestFetchPreloader.cpp | 1 + widget/windows/nsDataObj.cpp | 1 + xpcom/base/AppShutdown.cpp | 1 + xpcom/tests/gtest/TestEventPriorities.cpp | 1 + .../gtest/TestInputStreamLengthHelper.cpp | 1 + .../tests/gtest/TestMultiplexInputStream.cpp | 1 + .../gtest/TestNonBlockingAsyncInputStream.cpp | 1 + xpcom/tests/gtest/TestSlicedInputStream.cpp | 1 + xpcom/tests/gtest/TestThreadUtils.cpp | 1 + xpcom/threads/SharedThreadPool.cpp | 1 + xpcom/threads/SpinEventLoopUntil.h | 108 ++++++++++++++++++ xpcom/threads/ThreadEventTarget.cpp | 1 + xpcom/threads/moz.build | 1 + xpcom/threads/nsThread.cpp | 1 + xpcom/threads/nsThreadManager.cpp | 1 + xpcom/threads/nsThreadPool.cpp | 1 + xpcom/threads/nsThreadUtils.h | 94 +-------------- xpfe/appshell/AppWindow.cpp | 1 + 68 files changed, 175 insertions(+), 95 deletions(-) create mode 100644 xpcom/threads/SpinEventLoopUntil.h diff --git a/devtools/platform/nsJSInspector.cpp b/devtools/platform/nsJSInspector.cpp index aa74a1ed3d64..02822fb568a3 100644 --- a/devtools/platform/nsJSInspector.cpp +++ b/devtools/platform/nsJSInspector.cpp @@ -4,9 +4,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsJSInspector.h" -#include "nsThreadUtils.h" #include "jsfriendapi.h" #include "mozilla/HoldDropJSObjects.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/dom/ScriptSettings.h" #include "nsServiceManagerUtils.h" #include "nsMemory.h" diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 89708638e38b..48ae9b65f897 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -92,6 +92,7 @@ #include "mozilla/dom/ScriptSettings.h" #include "mozilla/Preferences.h" #include "mozilla/Likely.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/Sprintf.h" #include "mozilla/StorageAccess.h" #include "mozilla/Unused.h" diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index b3f6ac1a921d..ba2bd841eb18 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -88,6 +88,7 @@ #include "mozilla/dom/ScriptSettings.h" #include "mozilla/Preferences.h" #include "mozilla/Likely.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/Sprintf.h" #include "mozilla/Unused.h" diff --git a/dom/cache/Manager.cpp b/dom/cache/Manager.cpp index 07e0558760a5..04e18d095ee3 100644 --- a/dom/cache/Manager.cpp +++ b/dom/cache/Manager.cpp @@ -8,6 +8,7 @@ #include "mozilla/AutoRestore.h" #include "mozilla/Mutex.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticMutex.h" #include "mozilla/StaticPtr.h" #include "mozilla/Unused.h" diff --git a/dom/filehandle/ActorsParent.cpp b/dom/filehandle/ActorsParent.cpp index 7d72b05e94e4..f104d694bbaf 100644 --- a/dom/filehandle/ActorsParent.cpp +++ b/dom/filehandle/ActorsParent.cpp @@ -9,6 +9,7 @@ #include "mozilla/Assertions.h" #include "mozilla/Atomics.h" #include "mozilla/Attributes.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/Unused.h" #include "mozilla/dom/BlobImpl.h" #include "mozilla/dom/File.h" diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 0a06e613317d..596df7176d5a 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -84,6 +84,7 @@ #include "mozilla/SchedulerGroup.h" #include "mozilla/Scoped.h" #include "mozilla/SnappyCompressOutputStream.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPtr.h" #include "mozilla/TaskCategory.h" #include "mozilla/TimeStamp.h" diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 5e0cfbffe7aa..642622b403e3 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -39,6 +39,7 @@ #include "mozilla/RemoteLazyInputStreamChild.h" #include "mozilla/SchedulerGroup.h" #include "mozilla/SharedStyleSheetCache.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPrefs_fission.h" #include "mozilla/StaticPrefs_media.h" diff --git a/dom/localstorage/ActorsParent.cpp b/dom/localstorage/ActorsParent.cpp index 48b12ed6ff5d..2edab092ab67 100644 --- a/dom/localstorage/ActorsParent.cpp +++ b/dom/localstorage/ActorsParent.cpp @@ -46,6 +46,7 @@ #include "mozilla/ResultExtensions.h" #include "mozilla/ScopeExit.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPtr.h" #include "mozilla/StoragePrincipalHelper.h" diff --git a/dom/localstorage/LSObject.cpp b/dom/localstorage/LSObject.cpp index bb680d0958d3..ca019e5bb249 100644 --- a/dom/localstorage/LSObject.cpp +++ b/dom/localstorage/LSObject.cpp @@ -21,6 +21,7 @@ #include "mozilla/Preferences.h" #include "mozilla/RemoteLazyInputStreamThread.h" #include "mozilla/ScopeExit.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticMutex.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/StorageAccess.h" diff --git a/dom/media/fuzz/FuzzMedia.cpp b/dom/media/fuzz/FuzzMedia.cpp index f23abd6cfc3e..36515f5810e9 100644 --- a/dom/media/fuzz/FuzzMedia.cpp +++ b/dom/media/fuzz/FuzzMedia.cpp @@ -9,6 +9,7 @@ #include "FlacDemuxer.h" #include "FuzzingInterface.h" #include "mozilla/AbstractThread.h" +#include "mozilla/SpinEventLoopUntil.h" #include "MP3Demuxer.h" #include "MP4Demuxer.h" #include "OggDemuxer.h" diff --git a/dom/media/gmp/GMPServiceParent.cpp b/dom/media/gmp/GMPServiceParent.cpp index def1260f2d2a..0c056b246a55 100644 --- a/dom/media/gmp/GMPServiceParent.cpp +++ b/dom/media/gmp/GMPServiceParent.cpp @@ -24,6 +24,7 @@ #endif #include "VideoUtils.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPrefs_media.h" #include "mozilla/SyncRunnable.h" #include "mozilla/Unused.h" diff --git a/dom/media/gtest/GMPTestMonitor.h b/dom/media/gtest/GMPTestMonitor.h index ecd2d052d836..ae04ee83dd61 100644 --- a/dom/media/gtest/GMPTestMonitor.h +++ b/dom/media/gtest/GMPTestMonitor.h @@ -8,6 +8,7 @@ #include "nsThreadUtils.h" #include "mozilla/SchedulerGroup.h" +#include "mozilla/SpinEventLoopUntil.h" class GMPTestMonitor { public: diff --git a/dom/media/gtest/TestAudioTrackGraph.cpp b/dom/media/gtest/TestAudioTrackGraph.cpp index e231e14aeeb0..6cfb1b2cde7e 100644 --- a/dom/media/gtest/TestAudioTrackGraph.cpp +++ b/dom/media/gtest/TestAudioTrackGraph.cpp @@ -15,6 +15,7 @@ #endif // MOZ_WEBRTC #include "MockCubeb.h" #include "mozilla/Preferences.h" +#include "mozilla/SpinEventLoopUntil.h" #define DRIFT_BUFFERING_PREF "media.clockdrift.buffering" diff --git a/dom/media/gtest/TestCDMStorage.cpp b/dom/media/gtest/TestCDMStorage.cpp index 747a92d7fdfb..09f87fe07a96 100644 --- a/dom/media/gtest/TestCDMStorage.cpp +++ b/dom/media/gtest/TestCDMStorage.cpp @@ -12,6 +12,7 @@ #include "gtest/gtest.h" #include "mozilla/RefPtr.h" #include "mozilla/SchedulerGroup.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsIFile.h" #include "nsNSSComponent.h" //For EnsureNSSInitializedChromeOrContent #include "nsThreadUtils.h" diff --git a/dom/media/gtest/TestDriftCompensation.cpp b/dom/media/gtest/TestDriftCompensation.cpp index b03c6aa0532f..456da306401e 100644 --- a/dom/media/gtest/TestDriftCompensation.cpp +++ b/dom/media/gtest/TestDriftCompensation.cpp @@ -6,6 +6,7 @@ #include "gtest/gtest.h" #include "DriftCompensation.h" +#include "mozilla/SpinEventLoopUntil.h" using namespace mozilla; diff --git a/dom/media/gtest/TestMediaDataDecoder.cpp b/dom/media/gtest/TestMediaDataDecoder.cpp index f95adeefb738..f25ad048ee7f 100644 --- a/dom/media/gtest/TestMediaDataDecoder.cpp +++ b/dom/media/gtest/TestMediaDataDecoder.cpp @@ -12,6 +12,7 @@ #include "WebMDecoder.h" #include "WebMDemuxer.h" #include "mozilla/AbstractThread.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsMimeTypes.h" using namespace mozilla; diff --git a/dom/media/gtest/TestMediaDataEncoder.cpp b/dom/media/gtest/TestMediaDataEncoder.cpp index b94f61b98612..6adeb73f3de2 100644 --- a/dom/media/gtest/TestMediaDataEncoder.cpp +++ b/dom/media/gtest/TestMediaDataEncoder.cpp @@ -8,6 +8,7 @@ #include "AnnexB.h" #include "ImageContainer.h" #include "mozilla/AbstractThread.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/media/MediaUtils.h" // For media::Await #include "nsMimeTypes.h" #include "PEMFactory.h" diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 2910a25c3fa4..c74bb07b022f 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -48,6 +48,7 @@ #include "mozilla/LoadInfo.h" #include "mozilla/plugins/PluginBridge.h" #include "mozilla/plugins/PluginTypes.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/TextUtils.h" #include "mozilla/Preferences.h" #include "mozilla/ipc/URIUtils.h" diff --git a/dom/quota/ActorsParent.cpp b/dom/quota/ActorsParent.cpp index f2d0b9cb58d9..b216a099428c 100644 --- a/dom/quota/ActorsParent.cpp +++ b/dom/quota/ActorsParent.cpp @@ -55,6 +55,7 @@ #include "mozilla/ResultExtensions.h" #include "mozilla/ScopeExit.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPtr.h" #include "mozilla/Telemetry.h" diff --git a/dom/simpledb/ActorsParent.cpp b/dom/simpledb/ActorsParent.cpp index be31beb3c686..6bca477f1210 100644 --- a/dom/simpledb/ActorsParent.cpp +++ b/dom/simpledb/ActorsParent.cpp @@ -25,6 +25,7 @@ #include "mozilla/RefPtr.h" #include "mozilla/Result.h" #include "mozilla/ResultExtensions.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPtr.h" #include "mozilla/Unused.h" #include "mozilla/Variant.h" diff --git a/dom/storage/StorageObserver.cpp b/dom/storage/StorageObserver.cpp index 54a230bfe42a..e8eed3c4efd5 100644 --- a/dom/storage/StorageObserver.cpp +++ b/dom/storage/StorageObserver.cpp @@ -25,6 +25,7 @@ #include "mozilla/dom/LocalStorageCommon.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsServiceManagerUtils.h" namespace mozilla { diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index d54f6c39fa0f..bc7bb3af2b1a 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -36,6 +36,7 @@ #include "mozilla/LoadInfo.h" #include "mozilla/LoadContext.h" #include "mozilla/MemoryReporting.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPrefs_network.h" #include "mozilla/StaticPrefs_privacy.h" diff --git a/extensions/pref/autoconfig/src/nsAutoConfig.cpp b/extensions/pref/autoconfig/src/nsAutoConfig.cpp index 3495da36d5ba..d841512c93d9 100644 --- a/extensions/pref/autoconfig/src/nsAutoConfig.cpp +++ b/extensions/pref/autoconfig/src/nsAutoConfig.cpp @@ -28,6 +28,7 @@ #include "mozilla/IntegerPrintfMacros.h" #include "mozilla/Logging.h" +#include "mozilla/SpinEventLoopUntil.h" using mozilla::LogLevel; diff --git a/gfx/layers/ipc/CompositorBridgeChild.cpp b/gfx/layers/ipc/CompositorBridgeChild.cpp index 572837253a66..48d7819ab477 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.cpp +++ b/gfx/layers/ipc/CompositorBridgeChild.cpp @@ -42,6 +42,7 @@ #include "mozilla/dom/ContentChild.h" #include "mozilla/Unused.h" #include "mozilla/DebugOnly.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsThreadUtils.h" #if defined(XP_WIN) # include "WinUtils.h" diff --git a/gfx/layers/ipc/CompositorThread.cpp b/gfx/layers/ipc/CompositorThread.cpp index 4835af3a0062..53a23cbc6f3a 100644 --- a/gfx/layers/ipc/CompositorThread.cpp +++ b/gfx/layers/ipc/CompositorThread.cpp @@ -9,6 +9,7 @@ #include "MainThreadUtils.h" #include "VRManagerParent.h" #include "mozilla/BackgroundHangMonitor.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/layers/CanvasTranslator.h" #include "mozilla/layers/CompositorManagerParent.h" #include "mozilla/layers/ImageBridgeParent.h" diff --git a/ipc/glue/BackgroundImpl.cpp b/ipc/glue/BackgroundImpl.cpp index a68f2c79c3b2..4a2e88c75601 100644 --- a/ipc/glue/BackgroundImpl.cpp +++ b/ipc/glue/BackgroundImpl.cpp @@ -20,6 +20,7 @@ #include "mozilla/DebugOnly.h" #include "mozilla/MozPromise.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPtr.h" #include "mozilla/Unused.h" #include "mozilla/dom/ContentChild.h" diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 20c4f244dffa..a7d984fabcc4 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -47,6 +47,7 @@ #include "mozilla/Encoding.h" #include "mozilla/ErrorResult.h" #include "mozilla/Preferences.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/WeakPtr.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPrefs_javascript.h" diff --git a/layout/printing/ipc/RemotePrintJobChild.cpp b/layout/printing/ipc/RemotePrintJobChild.cpp index ba49bd4fdacc..a7b7f5cfaa10 100644 --- a/layout/printing/ipc/RemotePrintJobChild.cpp +++ b/layout/printing/ipc/RemotePrintJobChild.cpp @@ -6,6 +6,7 @@ #include "RemotePrintJobChild.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/Unused.h" #include "nsPagePrintTimer.h" #include "nsPrintJob.h" diff --git a/media/webrtc/signaling/gtest/mediapipeline_unittest.cpp b/media/webrtc/signaling/gtest/mediapipeline_unittest.cpp index 791680a35f8b..ba3a93b683fb 100644 --- a/media/webrtc/signaling/gtest/mediapipeline_unittest.cpp +++ b/media/webrtc/signaling/gtest/mediapipeline_unittest.cpp @@ -13,6 +13,7 @@ #include "AudioStreamTrack.h" #include "mozilla/Mutex.h" #include "mozilla/RefPtr.h" +#include "mozilla/SpinEventLoopUntil.h" #include "MediaPipeline.h" #include "MediaPipelineFilter.h" #include "MediaTrackGraph.h" diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index 082f9a83a766..9f55be419eb8 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -33,6 +33,7 @@ #include "mozilla/ScopeExit.h" #include "mozilla/Services.h" #include "mozilla/ServoStyleSet.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticMutex.h" #include "mozilla/StaticPrefsAll.h" #include "mozilla/SyncRunnable.h" diff --git a/netwerk/base/ProxyAutoConfig.cpp b/netwerk/base/ProxyAutoConfig.cpp index a89840ad3d65..6635d89de822 100644 --- a/netwerk/base/ProxyAutoConfig.cpp +++ b/netwerk/base/ProxyAutoConfig.cpp @@ -24,6 +24,7 @@ #include "prnetdb.h" #include "nsITimer.h" #include "mozilla/Atomics.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/net/DNS.h" #include "mozilla/Utf8.h" // mozilla::Utf8Unit #include "nsServiceManagerUtils.h" diff --git a/netwerk/base/nsAsyncRedirectVerifyHelper.cpp b/netwerk/base/nsAsyncRedirectVerifyHelper.cpp index 40e98b4c50c2..d61c00414ce3 100644 --- a/netwerk/base/nsAsyncRedirectVerifyHelper.cpp +++ b/netwerk/base/nsAsyncRedirectVerifyHelper.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Logging.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsAsyncRedirectVerifyHelper.h" #include "nsThreadUtils.h" #include "nsNetUtil.h" diff --git a/netwerk/base/nsSyncStreamListener.cpp b/netwerk/base/nsSyncStreamListener.cpp index 6dfc3a0b386b..9bfcd63d6743 100644 --- a/netwerk/base/nsSyncStreamListener.cpp +++ b/netwerk/base/nsSyncStreamListener.cpp @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "mozilla/SpinEventLoopUntil.h" #include "nsIOService.h" #include "nsSyncStreamListener.h" #include "nsThreadUtils.h" diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index b9f64caa5056..cad55e90a6a8 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -17,6 +17,7 @@ #include "NullHttpTransaction.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/Telemetry.h" #include "mozilla/Unused.h" #include "mozilla/net/DNS.h" diff --git a/netwerk/test/fuzz/FuzzingStreamListener.h b/netwerk/test/fuzz/FuzzingStreamListener.h index 9ec01a95c21b..97234bc7bafa 100644 --- a/netwerk/test/fuzz/FuzzingStreamListener.h +++ b/netwerk/test/fuzz/FuzzingStreamListener.h @@ -1,12 +1,12 @@ #ifndef FuzzingStreamListener_h__ #define FuzzingStreamListener_h__ +#include "mozilla/SpinEventLoopUntil.h" #include "nsCOMPtr.h" #include "nsNetCID.h" #include "nsString.h" #include "nsNetUtil.h" #include "nsIStreamListener.h" -#include "nsThreadUtils.h" namespace mozilla { namespace net { diff --git a/netwerk/test/fuzz/TestFtpFuzzing.cpp b/netwerk/test/fuzz/TestFtpFuzzing.cpp index ef918eff0e55..9fde50427944 100644 --- a/netwerk/test/fuzz/TestFtpFuzzing.cpp +++ b/netwerk/test/fuzz/TestFtpFuzzing.cpp @@ -1,4 +1,5 @@ #include "mozilla/Preferences.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsCOMPtr.h" #include "nsNetCID.h" diff --git a/netwerk/test/fuzz/TestHttpFuzzing.cpp b/netwerk/test/fuzz/TestHttpFuzzing.cpp index b21b3ff7aa9e..5aabd903d84c 100644 --- a/netwerk/test/fuzz/TestHttpFuzzing.cpp +++ b/netwerk/test/fuzz/TestHttpFuzzing.cpp @@ -1,5 +1,6 @@ #include "mozilla/LoadInfo.h" #include "mozilla/Preferences.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsCOMPtr.h" #include "nsNetCID.h" diff --git a/netwerk/test/fuzz/TestWebsocketFuzzing.cpp b/netwerk/test/fuzz/TestWebsocketFuzzing.cpp index 762b38025782..ce3668d680e9 100644 --- a/netwerk/test/fuzz/TestWebsocketFuzzing.cpp +++ b/netwerk/test/fuzz/TestWebsocketFuzzing.cpp @@ -2,6 +2,7 @@ #include "FuzzingInterface.h" #include "FuzzyLayer.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsComponentManagerUtils.h" #include "nsCOMPtr.h" #include "nsContentUtils.h" diff --git a/netwerk/test/gtest/TestBufferedInputStream.cpp b/netwerk/test/gtest/TestBufferedInputStream.cpp index b405f44c48e4..09527318c591 100644 --- a/netwerk/test/gtest/TestBufferedInputStream.cpp +++ b/netwerk/test/gtest/TestBufferedInputStream.cpp @@ -1,5 +1,6 @@ #include "gtest/gtest.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsBufferedStreams.h" #include "nsStreamUtils.h" #include "nsIThread.h" diff --git a/netwerk/test/gtest/TestCommon.h b/netwerk/test/gtest/TestCommon.h index a0d4d9a567c0..67ff55b1fbc5 100644 --- a/netwerk/test/gtest/TestCommon.h +++ b/netwerk/test/gtest/TestCommon.h @@ -8,6 +8,7 @@ #include #include "nsThreadUtils.h" #include "mozilla/Attributes.h" +#include "mozilla/SpinEventLoopUntil.h" //----------------------------------------------------------------------------- diff --git a/netwerk/test/gtest/TestMIMEInputStream.cpp b/netwerk/test/gtest/TestMIMEInputStream.cpp index a90d4d28aa38..ce7f5bd47d1f 100644 --- a/netwerk/test/gtest/TestMIMEInputStream.cpp +++ b/netwerk/test/gtest/TestMIMEInputStream.cpp @@ -1,6 +1,7 @@ #include "gtest/gtest.h" #include "Helpers.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsComponentManagerUtils.h" #include "nsCOMPtr.h" #include "nsStreamUtils.h" diff --git a/netwerk/test/gtest/TestPartiallySeekableInputStream.cpp b/netwerk/test/gtest/TestPartiallySeekableInputStream.cpp index 306e01c5b5bf..1dffd6fcafe0 100644 --- a/netwerk/test/gtest/TestPartiallySeekableInputStream.cpp +++ b/netwerk/test/gtest/TestPartiallySeekableInputStream.cpp @@ -5,6 +5,7 @@ #include "nsStreamUtils.h" #include "nsString.h" #include "nsStringStream.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/net/PartiallySeekableInputStream.h" using mozilla::GetCurrentSerialEventTarget; diff --git a/storage/mozStorageConnection.cpp b/storage/mozStorageConnection.cpp index 13c44e97aa37..3cbc5f629091 100644 --- a/storage/mozStorageConnection.cpp +++ b/storage/mozStorageConnection.cpp @@ -19,6 +19,7 @@ #include "mozilla/Unused.h" #include "mozilla/dom/quota/QuotaObject.h" #include "mozilla/ScopeExit.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPrefs_storage.h" #include "mozIStorageCompletionCallback.h" diff --git a/storage/mozStorageService.cpp b/storage/mozStorageService.cpp index 0669ae77ed1f..57a87dec0dce 100644 --- a/storage/mozStorageService.cpp +++ b/storage/mozStorageService.cpp @@ -6,6 +6,7 @@ #include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozStorageService.h" #include "mozStorageConnection.h" diff --git a/toolkit/components/places/Database.cpp b/toolkit/components/places/Database.cpp index 906510033e30..fbd616a7720d 100644 --- a/toolkit/components/places/Database.cpp +++ b/toolkit/components/places/Database.cpp @@ -6,6 +6,7 @@ #include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" #include "mozilla/ScopeExit.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/JSONWriter.h" #include "Database.h" diff --git a/toolkit/components/places/tests/gtest/places_test_harness.h b/toolkit/components/places/tests/gtest/places_test_harness.h index a25be1e0a289..f6531fb7b32f 100644 --- a/toolkit/components/places/tests/gtest/places_test_harness.h +++ b/toolkit/components/places/tests/gtest/places_test_harness.h @@ -16,6 +16,7 @@ #include "nsIThread.h" #include "nsIURI.h" #include "mozilla/IHistory.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozIStorageConnection.h" #include "mozIStorageStatement.h" #include "mozIStorageAsyncStatement.h" diff --git a/toolkit/components/places/tests/gtest/test_IHistory.cpp b/toolkit/components/places/tests/gtest/test_IHistory.cpp index 1f518f584831..e7123cdb6102 100644 --- a/toolkit/components/places/tests/gtest/test_IHistory.cpp +++ b/toolkit/components/places/tests/gtest/test_IHistory.cpp @@ -9,6 +9,7 @@ #include "nsIPrefService.h" #include "nsString.h" #include "mozilla/Attributes.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPrefs_layout.h" #include "nsNetUtil.h" diff --git a/toolkit/components/printingui/ipc/nsPrintingProxy.cpp b/toolkit/components/printingui/ipc/nsPrintingProxy.cpp index 6a3578d64511..bad829b56220 100644 --- a/toolkit/components/printingui/ipc/nsPrintingProxy.cpp +++ b/toolkit/components/printingui/ipc/nsPrintingProxy.cpp @@ -10,6 +10,7 @@ #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/BrowserChild.h" #include "mozilla/layout/RemotePrintJobChild.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/Unused.h" #include "nsIDocShell.h" #include "nsIPrintingPromptService.h" diff --git a/toolkit/components/url-classifier/tests/gtest/Common.cpp b/toolkit/components/url-classifier/tests/gtest/Common.cpp index 78f5919653d0..3a46d476a672 100644 --- a/toolkit/components/url-classifier/tests/gtest/Common.cpp +++ b/toolkit/components/url-classifier/tests/gtest/Common.cpp @@ -9,6 +9,7 @@ #include "HashStore.h" #include "LookupCacheV4.h" #include "mozilla/Components.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/Unused.h" #include "nsAppDirectoryServiceDefs.h" #include "nsIThread.h" diff --git a/toolkit/xre/ProfileReset.cpp b/toolkit/xre/ProfileReset.cpp index 80ea7bdf4938..f181e347886c 100644 --- a/toolkit/xre/ProfileReset.cpp +++ b/toolkit/xre/ProfileReset.cpp @@ -20,6 +20,7 @@ #include "mozilla/XREAppData.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/Unused.h" #include "prtime.h" diff --git a/uriloader/preload/gtest/TestFetchPreloader.cpp b/uriloader/preload/gtest/TestFetchPreloader.cpp index 1531ef471a7c..4d4d2b5103ce 100644 --- a/uriloader/preload/gtest/TestFetchPreloader.cpp +++ b/uriloader/preload/gtest/TestFetchPreloader.cpp @@ -6,6 +6,7 @@ #include "mozilla/FetchPreloader.h" #include "mozilla/Maybe.h" #include "mozilla/PreloadHashKey.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsNetUtil.h" #include "nsIChannel.h" #include "nsIStreamListener.h" diff --git a/widget/windows/nsDataObj.cpp b/widget/windows/nsDataObj.cpp index b267608b4ec8..5fb55247960a 100644 --- a/widget/windows/nsDataObj.cpp +++ b/widget/windows/nsDataObj.cpp @@ -25,6 +25,7 @@ #include "nsIURL.h" #include "nsNetUtil.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/Unused.h" #include "nsIOutputStream.h" #include "nscore.h" diff --git a/xpcom/base/AppShutdown.cpp b/xpcom/base/AppShutdown.cpp index c53eda4f6285..130027084c5a 100644 --- a/xpcom/base/AppShutdown.cpp +++ b/xpcom/base/AppShutdown.cpp @@ -17,6 +17,7 @@ #include "mozilla/PoisonIOInterposer.h" #include "mozilla/Printf.h" #include "mozilla/scache/StartupCache.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StartupTimeline.h" #include "mozilla/StaticPrefs_toolkit.h" #include "mozilla/LateWriteChecks.h" diff --git a/xpcom/tests/gtest/TestEventPriorities.cpp b/xpcom/tests/gtest/TestEventPriorities.cpp index 00922f80eed7..dfe222ce01c4 100644 --- a/xpcom/tests/gtest/TestEventPriorities.cpp +++ b/xpcom/tests/gtest/TestEventPriorities.cpp @@ -9,6 +9,7 @@ #include "nsXPCOM.h" #include "nsThreadUtils.h" #include "gtest/gtest.h" +#include "mozilla/SpinEventLoopUntil.h" #include diff --git a/xpcom/tests/gtest/TestInputStreamLengthHelper.cpp b/xpcom/tests/gtest/TestInputStreamLengthHelper.cpp index b9fff721007d..2ae008c2c720 100644 --- a/xpcom/tests/gtest/TestInputStreamLengthHelper.cpp +++ b/xpcom/tests/gtest/TestInputStreamLengthHelper.cpp @@ -1,6 +1,7 @@ #include "gtest/gtest.h" #include "mozilla/InputStreamLengthHelper.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsCOMPtr.h" #include "nsIInputStream.h" #include "nsStreamUtils.h" diff --git a/xpcom/tests/gtest/TestMultiplexInputStream.cpp b/xpcom/tests/gtest/TestMultiplexInputStream.cpp index 61174d4391b3..b607208a8db7 100644 --- a/xpcom/tests/gtest/TestMultiplexInputStream.cpp +++ b/xpcom/tests/gtest/TestMultiplexInputStream.cpp @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "gtest/gtest.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsIAsyncInputStream.h" #include "nsComponentManagerUtils.h" #include "nsIInputStream.h" diff --git a/xpcom/tests/gtest/TestNonBlockingAsyncInputStream.cpp b/xpcom/tests/gtest/TestNonBlockingAsyncInputStream.cpp index 29c2556a54a4..a961d8c14f80 100644 --- a/xpcom/tests/gtest/TestNonBlockingAsyncInputStream.cpp +++ b/xpcom/tests/gtest/TestNonBlockingAsyncInputStream.cpp @@ -1,6 +1,7 @@ #include "gtest/gtest.h" #include "mozilla/NonBlockingAsyncInputStream.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsIAsyncInputStream.h" #include "nsStreamUtils.h" #include "nsString.h" diff --git a/xpcom/tests/gtest/TestSlicedInputStream.cpp b/xpcom/tests/gtest/TestSlicedInputStream.cpp index b5c32f4e8888..269e7f1e2f31 100644 --- a/xpcom/tests/gtest/TestSlicedInputStream.cpp +++ b/xpcom/tests/gtest/TestSlicedInputStream.cpp @@ -1,6 +1,7 @@ #include "gtest/gtest.h" #include "mozilla/SlicedInputStream.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsCOMPtr.h" #include "nsIInputStream.h" #include "nsIPipe.h" diff --git a/xpcom/tests/gtest/TestThreadUtils.cpp b/xpcom/tests/gtest/TestThreadUtils.cpp index 34af41695f95..897f43e17dc7 100644 --- a/xpcom/tests/gtest/TestThreadUtils.cpp +++ b/xpcom/tests/gtest/TestThreadUtils.cpp @@ -8,6 +8,7 @@ #include "nsThreadUtils.h" #include "mozilla/IdleTaskRunner.h" #include "mozilla/RefCounted.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/UniquePtr.h" #include "gtest/gtest.h" diff --git a/xpcom/threads/SharedThreadPool.cpp b/xpcom/threads/SharedThreadPool.cpp index 5f77a64e010c..fede9a2f394b 100644 --- a/xpcom/threads/SharedThreadPool.cpp +++ b/xpcom/threads/SharedThreadPool.cpp @@ -8,6 +8,7 @@ #include "mozilla/Monitor.h" #include "mozilla/ReentrantMonitor.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPtr.h" #include "nsDataHashtable.h" #include "nsXPCOMCIDInternal.h" diff --git a/xpcom/threads/SpinEventLoopUntil.h b/xpcom/threads/SpinEventLoopUntil.h new file mode 100644 index 000000000000..398c7084a27f --- /dev/null +++ b/xpcom/threads/SpinEventLoopUntil.h @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef xpcom_threads_SpinEventLoopUntil_h__ +#define xpcom_threads_SpinEventLoopUntil_h__ + +#include "MainThreadUtils.h" +#include "mozilla/Maybe.h" +#include "nsThreadUtils.h" +#include "xpcpublic.h" + +class nsIThread; + +// A wrapper for nested event loops. +// +// This function is intended to make code more obvious (do you remember +// what NS_ProcessNextEvent(nullptr, true) means?) and slightly more +// efficient, as people often pass nullptr or NS_GetCurrentThread to +// NS_ProcessNextEvent, which results in needless querying of the current +// thread every time through the loop. +// +// You should use this function in preference to NS_ProcessNextEvent inside +// a loop unless one of the following is true: +// +// * You need to pass `false` to NS_ProcessNextEvent; or +// * You need to do unusual things around the call to NS_ProcessNextEvent, +// such as unlocking mutexes that you are holding. +// +// If you *do* need to call NS_ProcessNextEvent manually, please do call +// NS_GetCurrentThread() outside of your loop and pass the returned pointer +// into NS_ProcessNextEvent for a tiny efficiency win. +namespace mozilla { + +// You should normally not need to deal with this template parameter. If +// you enjoy esoteric event loop details, read on. +// +// If you specify that NS_ProcessNextEvent wait for an event, it is possible +// for NS_ProcessNextEvent to return false, i.e. to indicate that an event +// was not processed. This can only happen when the thread has been shut +// down by another thread, but is still attempting to process events outside +// of a nested event loop. +// +// This behavior is admittedly strange. The scenario it deals with is the +// following: +// +// * The current thread has been shut down by some owner thread. +// * The current thread is spinning an event loop waiting for some condition +// to become true. +// * Said condition is actually being fulfilled by another thread, so there +// are timing issues in play. +// +// Thus, there is a small window where the current thread's event loop +// spinning can check the condition, find it false, and call +// NS_ProcessNextEvent to wait for another event. But we don't actually +// want it to wait indefinitely, because there might not be any other events +// in the event loop, and the current thread can't accept dispatched events +// because it's being shut down. Thus, actually blocking would hang the +// thread, which is bad. The solution, then, is to detect such a scenario +// and not actually block inside NS_ProcessNextEvent. +// +// But this is a problem, because we want to return the status of +// NS_ProcessNextEvent to the caller of SpinEventLoopUntil if possible. In +// the above scenario, however, we'd stop spinning prematurely and cause +// all sorts of havoc. We therefore have this template parameter to +// control whether errors are ignored or passed out to the caller of +// SpinEventLoopUntil. The latter is the default; if you find yourself +// wanting to use the former, you should think long and hard before doing +// so, and write a comment like this defending your choice. + +enum class ProcessFailureBehavior { + IgnoreAndContinue, + ReportToCaller, +}; + +template < + ProcessFailureBehavior Behavior = ProcessFailureBehavior::ReportToCaller, + typename Pred> +bool SpinEventLoopUntil(Pred&& aPredicate, nsIThread* aThread = nullptr) { + nsIThread* thread = aThread ? aThread : NS_GetCurrentThread(); + + // From a latency perspective, spinning the event loop is like leaving script + // and returning to the event loop. Tell the watchdog we stopped running + // script (until we return). + mozilla::Maybe asa; + if (NS_IsMainThread()) { + asa.emplace(false); + } + + while (!aPredicate()) { + bool didSomething = NS_ProcessNextEvent(thread, true); + + if (Behavior == ProcessFailureBehavior::IgnoreAndContinue) { + // Don't care what happened, continue on. + continue; + } else if (!didSomething) { + return false; + } + } + + return true; +} + +} // namespace mozilla + +#endif // xpcom_threads_SpinEventLoopUntil_h__ diff --git a/xpcom/threads/ThreadEventTarget.cpp b/xpcom/threads/ThreadEventTarget.cpp index c76986d82dfc..75a109cceb50 100644 --- a/xpcom/threads/ThreadEventTarget.cpp +++ b/xpcom/threads/ThreadEventTarget.cpp @@ -8,6 +8,7 @@ #include "mozilla/ThreadEventQueue.h" #include "LeakRefPtr.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/TimeStamp.h" #include "nsComponentManagerUtils.h" #include "nsITimer.h" diff --git a/xpcom/threads/moz.build b/xpcom/threads/moz.build index e588d45284bd..0bd525e9e22b 100644 --- a/xpcom/threads/moz.build +++ b/xpcom/threads/moz.build @@ -64,6 +64,7 @@ EXPORTS.mozilla += [ "RWLock.h", "SchedulerGroup.h", "SharedThreadPool.h", + "SpinEventLoopUntil.h", "StateMirroring.h", "StateWatching.h", "SynchronizedEventQueue.h", diff --git a/xpcom/threads/nsThread.cpp b/xpcom/threads/nsThread.cpp index 5c143579614e..8c27b8d3c0f2 100644 --- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -31,6 +31,7 @@ #include "mozilla/Preferences.h" #include "mozilla/SchedulerGroup.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPrefs_threads.h" #include "mozilla/TaskController.h" #include "nsXPCOMPrivate.h" diff --git a/xpcom/threads/nsThreadManager.cpp b/xpcom/threads/nsThreadManager.cpp index c9fdf15b3234..7dfb54284290 100644 --- a/xpcom/threads/nsThreadManager.cpp +++ b/xpcom/threads/nsThreadManager.cpp @@ -17,6 +17,7 @@ #include "mozilla/InputTaskManager.h" #include "mozilla/Mutex.h" #include "mozilla/Preferences.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/StaticPtr.h" #include "mozilla/TaskQueue.h" #include "mozilla/ThreadEventQueue.h" diff --git a/xpcom/threads/nsThreadPool.cpp b/xpcom/threads/nsThreadPool.cpp index a60e498751de..32789240fdb6 100644 --- a/xpcom/threads/nsThreadPool.cpp +++ b/xpcom/threads/nsThreadPool.cpp @@ -13,6 +13,7 @@ #include "prinrval.h" #include "mozilla/Logging.h" #include "mozilla/SchedulerGroup.h" +#include "mozilla/SpinEventLoopUntil.h" #include "nsThreadSyncDispatch.h" #include diff --git a/xpcom/threads/nsThreadUtils.h b/xpcom/threads/nsThreadUtils.h index e1cd094d6271..f7c907ab38ae 100644 --- a/xpcom/threads/nsThreadUtils.h +++ b/xpcom/threads/nsThreadUtils.h @@ -25,15 +25,14 @@ #include "nsIIdleRunnable.h" #include "nsINamed.h" #include "nsIRunnable.h" -#include "nsIThread.h" #include "nsIThreadManager.h" #include "nsITimer.h" #include "nsString.h" #include "prinrval.h" #include "prthread.h" -#include "xpcpublic.h" class MessageLoop; +class nsIThread; //----------------------------------------------------------------------------- // These methods are alternatives to the methods on nsIThreadManager, provided @@ -283,97 +282,6 @@ extern bool NS_HasPendingEvents(nsIThread* aThread = nullptr); extern bool NS_ProcessNextEvent(nsIThread* aThread = nullptr, bool aMayWait = true); -// A wrapper for nested event loops. -// -// This function is intended to make code more obvious (do you remember -// what NS_ProcessNextEvent(nullptr, true) means?) and slightly more -// efficient, as people often pass nullptr or NS_GetCurrentThread to -// NS_ProcessNextEvent, which results in needless querying of the current -// thread every time through the loop. -// -// You should use this function in preference to NS_ProcessNextEvent inside -// a loop unless one of the following is true: -// -// * You need to pass `false` to NS_ProcessNextEvent; or -// * You need to do unusual things around the call to NS_ProcessNextEvent, -// such as unlocking mutexes that you are holding. -// -// If you *do* need to call NS_ProcessNextEvent manually, please do call -// NS_GetCurrentThread() outside of your loop and pass the returned pointer -// into NS_ProcessNextEvent for a tiny efficiency win. -namespace mozilla { - -// You should normally not need to deal with this template parameter. If -// you enjoy esoteric event loop details, read on. -// -// If you specify that NS_ProcessNextEvent wait for an event, it is possible -// for NS_ProcessNextEvent to return false, i.e. to indicate that an event -// was not processed. This can only happen when the thread has been shut -// down by another thread, but is still attempting to process events outside -// of a nested event loop. -// -// This behavior is admittedly strange. The scenario it deals with is the -// following: -// -// * The current thread has been shut down by some owner thread. -// * The current thread is spinning an event loop waiting for some condition -// to become true. -// * Said condition is actually being fulfilled by another thread, so there -// are timing issues in play. -// -// Thus, there is a small window where the current thread's event loop -// spinning can check the condition, find it false, and call -// NS_ProcessNextEvent to wait for another event. But we don't actually -// want it to wait indefinitely, because there might not be any other events -// in the event loop, and the current thread can't accept dispatched events -// because it's being shut down. Thus, actually blocking would hang the -// thread, which is bad. The solution, then, is to detect such a scenario -// and not actually block inside NS_ProcessNextEvent. -// -// But this is a problem, because we want to return the status of -// NS_ProcessNextEvent to the caller of SpinEventLoopUntil if possible. In -// the above scenario, however, we'd stop spinning prematurely and cause -// all sorts of havoc. We therefore have this template parameter to -// control whether errors are ignored or passed out to the caller of -// SpinEventLoopUntil. The latter is the default; if you find yourself -// wanting to use the former, you should think long and hard before doing -// so, and write a comment like this defending your choice. - -enum class ProcessFailureBehavior { - IgnoreAndContinue, - ReportToCaller, -}; - -template < - ProcessFailureBehavior Behavior = ProcessFailureBehavior::ReportToCaller, - typename Pred> -bool SpinEventLoopUntil(Pred&& aPredicate, nsIThread* aThread = nullptr) { - nsIThread* thread = aThread ? aThread : NS_GetCurrentThread(); - - // From a latency perspective, spinning the event loop is like leaving script - // and returning to the event loop. Tell the watchdog we stopped running - // script (until we return). - mozilla::Maybe asa; - if (NS_IsMainThread()) { - asa.emplace(false); - } - - while (!aPredicate()) { - bool didSomething = NS_ProcessNextEvent(thread, true); - - if (Behavior == ProcessFailureBehavior::IgnoreAndContinue) { - // Don't care what happened, continue on. - continue; - } else if (!didSomething) { - return false; - } - } - - return true; -} - -} // namespace mozilla - /** * Returns true if we're in the compositor thread. * diff --git a/xpfe/appshell/AppWindow.cpp b/xpfe/appshell/AppWindow.cpp index 8b361e2f84de..c6eeac6bb478 100644 --- a/xpfe/appshell/AppWindow.cpp +++ b/xpfe/appshell/AppWindow.cpp @@ -56,6 +56,7 @@ #include "mozilla/Preferences.h" #include "mozilla/PresShell.h" #include "mozilla/Services.h" +#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/dom/BarProps.h" #include "mozilla/dom/DOMRect.h" #include "mozilla/dom/Element.h"